
#include "SDK30.H"

#ifdef _DEPRECATED_SDK71_
#include "deprecated.h"
#endif

#ifdef IMAM_COMMS
#include "linklayer.h"
#include "gprs_lib.h"

#ifdef _SSL_ENABLE_
#include <SSL_.h>
#endif

#endif

#include "_emvdctag_.h"
#include "_emvdc_.h"
#include "del_lib.h"		
#include "bitmap.h"
#include "servcust.h"

#include <fm_interApp.h>
#include <fm_proto.h>
#include <fm_HMIService.h>
#include <fm_genpinpad.h>

#ifdef IMAM_COMMS
#include <fm_comms.h>
#endif

#include "dl_iso8583.h"
#include "dl_iso8583_defs_1993.h"
#include "dl_output.h" // for 'DL_OUTPUT_Hex'
#include "isogen.h" // for 'DL_OUTPUT_Hex'
#include "profile.h"
#include "crypto_lib.h"

//#include "profile.h"

//typedef unsigned char byte;
//typedef unsigned char uint8;

#define APP_BIT			"BOLONAPP"
#define TMS_BIT			"BOLONTMS"
#define APP_END			"BOLONEND"

//#define KARTUDEMO
//#define APP_ECR
//#define NO_PINPAD

typedef struct
{
	char Filename[100];
	S_FS_FILE	*fh;
	int index;
} FMFILE;

#define HOST_MAS  "HOST"

#define TMS_SETTING		"/"HOST_MAS"/PRFOLE.TMS"
#ifdef APP_ECR
#define FN_SETTING		"/"HOST_MAS"/MSTSET.DAT"

#define CRD_MAX_PAN_LEN					19
#define CRD_TRACK2_MAX_LEN				37

#define SIZE_PIN_BLOCK    16
typedef struct mastersetting_t
{
//	byte coms;
	unsigned long coms;// imam 

	byte rfu[3];
}mastersetting_t;


typedef struct
{
	int NeedSendAgain;
	int len;
	byte data[1024*5];
}combuffer;
#define BUFFER_MAX 1024*5

static mastersetting_t mstset;

static combuffer  combuf;

//static unsigned int COMECR;
static unsigned long COMECR;
static char COMECR_STR[6];
int ExecutM(void);
void StateHeaders(int st);

typedef struct stCard
{
    uint8  pucPan[19]; 
    uint8  unPanlen;
    uint8 puctrack2[128];
    uint8 ucTrack2Len;
		 
}stCard;

static stCard stCardData;

FILE *handle=NULL;
void initECR(NO_SEGMENT no);
extern int GET_CHAR(void);


typedef struct
{
	uint8 errocode;
	uint8 track1[128];
	uint8 lengthtrack1;
	uint8 track2[128];
	uint8 lengthtrack2;
	uint8 pValue;
	uint8 ATR[32];
}peripread;


typedef enum
{
  prTrackError,
  prTimeOut,
  prKeyPressed,
  prReadTrack2,
  prKeyError,
  prSmartError,
  prSmartRead,
  prSmartRemoved,
  prCommsInterrupt,
  prReadTrack1 = 0x30,
  prReadTrack12 = 0x33,
  prTrackRead = 0x80
} peripheralResult_t;

#define TRACK2_EXIST	0x01
#define TRACK1_EXIST	0x02
#define MAX_PAN_BNI   8

#endif


#define __ENTER_KEY		-1
#define __BACK_KEY		-2
#define __EXIT_KEY		-3
#define NUMBER_OF_ITEMS(a)			(sizeof(a)/sizeof((a)[0]))

extern int DisplayHeaderStatus;
DATE g_date;

void CallApp(unsigned short AppNo, unsigned short evtid);
char * dpmThisApplicationName(void);
extern int PasswordEntryTime(unsigned char * ucTrack2, int lenpan ,char *pwd,int line, int col,int nMinLen,
					   int nMaxLen, int instar, int nTimeout );
#ifdef 		_PASS_GEN_
extern int GetSecurityKey(void);
#endif

int DriveInit(void);
void DriveTerm(void);

ST_appreg totapreg;

unsigned short appid_act;


const char *MasterMenu[] =
{
	"About",
#ifdef APP_ECR
	//"ECR Setting",
#endif
};

#define TMS_OK   "OK_JON"
#define TMS_KO   "KO_JEX"
#define TMS_EX   "EX"


static const unsigned char appname[]    = "PINPAD\0";

static uint8 animFlag;

StructListe Menu;
static int DHeaderStatus;



#define APP_PAR_FILE_NAMEM	"/"HOST_MAS"/APPPIN.DAT"
#define ADF_SGN_DISKM	"TEMP"
#define MAX_FILE_DELTA	 5120

int SoftwareActivate( const char *szName );

int __SoftwareActivateM( const char *szName )
{
	int resiu=-1;
	char nameTemp[40];
       	

   memset(nameTemp,0x00,sizeof nameTemp);
   //     sprintf(nameTemp,"%s/35220328.AGN",ADF_SGN_DISKM);
	  sprintf(nameTemp,"TEMP");
	resiu = SoftwareActivate(nameTemp);

	_trace4("SoftwareActivate : disk %s, retval %d", nameTemp, resiu);
	ttestall( 0, 200 );
	return resiu;
}


int disk_createM(char* i_pc_diskpath , int i_l_disksize, uint8 mem_type)
{
	S_FS_PARAM_CREATE ParamCreat;
	int Ret , Ret1;
	char msg[50];
	int l_b_ret = TRUE;
	unsigned long i_l=i_l_disksize;
	if(mem_type)
		ParamCreat.Mode = FS_WRITEONCE;	//flash
	else
		ParamCreat.Mode = FS_WRITEMANY;	//ram

    	sprintf(msg, "/%s", i_pc_diskpath);
	Ret = FS_mount(msg,&ParamCreat.Mode);
	//check the disk exists or not
	switch(Ret)
	{
	case FS_OK :
		break; //existed
	case FS_KO :
		//create the disk
		strcpy(ParamCreat.Label ,i_pc_diskpath);
		ParamCreat.NbFichierMax = 30;
	    ParamCreat.AccessMode = FS_WRTMOD;
		ParamCreat.IdentZone = FS_WO_ZONE_DATA;
		Ret1 = FS_dskcreate(&ParamCreat,(unsigned long*)&i_l);
		if(Ret1 != FS_OK)
		{
			l_b_ret = FALSE;
		}
		else
		{
			//format
			Ret1 = FS_format(msg , FS_WRTMOD, 30);			
			if (Ret1 != FS_OK)				
				l_b_ret = FALSE;			
			else
			{			
				Ret = FS_mount(msg,&ParamCreat.Mode);
				if(Ret != FS_OK)			
					l_b_ret = FALSE;			
			}
		}
		break;
	default :
		l_b_ret = FALSE;
		break;
	}
	if(l_b_ret == TRUE)
		return TRUE;
	ttestall(0, 500);
	return FALSE;

}



int  UploadToDiskTempM(uint8 *buffer, uint32 length)
{
uint8 *	ptr=buffer;
//uint8 	more_records	= 0;//ptr[0];
int 		iRet;
uint32 len;
//FMFILE * fid1;
S_FS_FILE *fh; 

char openMode[5];
char nameTemp[40];
	
	

   memset(nameTemp,0x00,sizeof nameTemp);

      strcpy(openMode,"a");
      sprintf(nameTemp,"/%s/%s.AGN",ADF_SGN_DISKM,"35220328");

	

	   	  
	len = length;
	fh= FS_open(nameTemp, openMode);
	if (fh==NULL)
	//if( (fh= FS_open(nameTemp, openMode)))
	//if( (fid1= FM_fopen(nameTemp, openMode)) == 0)
	   {
	     
		//sysDisplayError("NVM OPEN FAILED", 1000);
		return -1;
	    }

	iRet=FS_write ( ptr, 1, len, fh);// != len/2)
//	iRet=FM_fwrite( ptr, 1, len, fid1);// != len/2)
	_trace4("Fwrite %d==%s",iRet,nameTemp);
	//FM_fclose(fid1);
	
	FS_close(fh);


  	return 1 ;

}



int OutPackM()
{

    int ret=23, iRet;
//    unsigned int  i=0, total=0;
    unsigned long long  len;
 //   char nameNewF[40];
    uint8 *buf;
    S_FS_FILE * t; 
 unsigned long loop,arrayF, i ,total=0;

DriveInit();
 t= FS_open(APP_PAR_FILE_NAMEM,"r");

if (FS_exist(APP_PAR_FILE_NAMEM)==FS_OK)
	  _trace4("FILE OK");
else 
	  _trace4("FILE KO");


  arrayF= FS_length(t);

 if ((arrayF%MAX_FILE_DELTA)==0)
 	
             loop=arrayF/MAX_FILE_DELTA;
 else
 	 loop=1+(arrayF/MAX_FILE_DELTA);

	FS_close(t);

	iRet = disk_createM(ADF_SGN_DISKM ,  512 * 1024, 0);
	_trace4("disk Create %d",iRet);
	if(iRet==FALSE)
		return -2;	
 _trace4("Execute %u loop %u  %u, %u  ", arrayF, loop,arrayF/MAX_FILE_DELTA,1+arrayF/MAX_FILE_DELTA );
//	return 0;

 // _trace4("Execute %d loop%d  ", arrayF, loop);

   for (i=0;i<loop;i++)
  	{    
	  	 buf=(uint8 *)umalloc(MAX_FILE_DELTA * (sizeof (uint8)));
		
		 t= FS_open(APP_PAR_FILE_NAMEM,"r");
			 
		 if (t)
		    {   iRet= FS_seek  ( t,  MAX_FILE_DELTA*i,FS_SEEKCUR);
			 _trace4("Seek %d",iRet);
				len= FS_read(buf, 1,MAX_FILE_DELTA,t);
				if (len>0)
				     {  _trace4("Execute %u loop%u trace %u ", arrayF, loop, i);
				       // _trace_DSP2("Check ", buf,20);
					   ret= UploadToDiskTempM(buf,len);  	
					
					_trace4("ret upload ret=%d",ret);
					}
				 total+=len;
				_trace4("ret upload ret=%d,total %d", ret,total);
				FS_close(t);
			   	   	   
			}
		else
			{
			 ret=-90;
			 break;
			}
		
		 
		    ufree(buf);
			if (i>35)
				break;
	     	}

   DriveTerm();
   return ret;
}


int ExecutM(void)
{
  _trace4("Execute");

   if (OutPackM()>0)
 	         	{  _trace4("Execute1");

			if ( __SoftwareActivateM(NULL)==0)
				{
				  StateHeaders(0);
				 pp_display_clear(0);
				  pp_settittle("PINPAD");
                       	pp_display_text(1,0, "PROSESS WAIT", PT_ALIGN_CENTER);
				pp_display_text(2,0, "ACTIVE ", PT_ALIGN_CENTER);
				pp_display_text(3,0, "NEW APP", PT_ALIGN_CENTER);
				buzzer (10);
		             ttestall(0,200);
			          
				exit(0);
				}
   	}
   else
   	{ _trace4("Execute3");
   	  StateHeaders(0);
				 pp_display_clear(0);
				 pp_settittle("PINPAD");
                       	pp_display_text(1,0, "PROSESS", PT_ALIGN_CENTER);
				pp_display_text(2,0, "ACTIVE ", PT_ALIGN_CENTER);
				pp_display_text(3,0, "FAILED", PT_ALIGN_CENTER);
				buzzer (100);
				ttestall(0, 5);
   	return -9;
   	}
    FS_unmount (APP_PAR_FILE_NAMEM);
   
   return 0;
}

#ifdef APP_ECR

int ECR_CallService(int no, byte *buffer, int *len, char *com_ecr);
/* Task state                     */
//static byte incomingdata=FALSE;
static long com_is_busy = FALSE;
#define TASK_OPEN        0
#define TASK_RECEPT      1
#define TASK_READING     2
/* Parameters of COM_EVENT entry point */
static S_COMIN             param_comin;
static S_COMOUT            param_comout;
/* My application number */
static NO_SEGMENT          appli_number;
/* protocol task handle : see OEM.H for description */
static t_topstack         *pttask;
/* Task state */
static unsigned char       task_state;
/* Task number of M2OS */
static unsigned short      m2os_task;
/* Stack of protocol Task */
#define PROTOCOLE_STACK_SIZE    2048/2
static unsigned long *protocole_stack[PROTOCOLE_STACK_SIZE];
/* System Stack size */
#define SYSTEM_STACK_SIZE      800
#endif

/*void RunEvent4App(e_eventtype eventid)
{
	int i, j;
	

	for (i=0;i<totapreg.totapp;i++)
	{
		for (j=0;j<50;j++)		
			if (totapreg.stap[i].evtsupport[j]==eventid)
				CallApp(totapreg.stap[i].apptype,eventid);		
	}

}*/
const unsigned char idle_logo[]=
{

	0, 128,
	0x00,
	0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00,
	0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x8F, 0x8F, 0xC7, 0xC7, 0xC7, 0xC7, 0x87,
	0x87, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x1F, 0x3F,
	0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07,
	0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xF8, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x00,
	0xFF, 0,
	0, 128,
	0x00,
	0xE0, 0xC0, 0x81, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xC0, 0x00,
	0x00, 0x01, 0x03, 0x0F, 0x1F, 0x00, 0x00, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFE,
	0xFF, 0xCF, 0xC7, 0xC7, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFC, 0xF8, 0xF0, 0xE0, 0x80,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0xFF, 0,
	0, 128,
	0x00,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xC0, 0x80, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x0F,
	0x46, 0xE0, 0xF0, 0xF0, 0xE0, 0xC0, 0x80, 0x80, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F,
	0x3F, 0x3F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
	0x01, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F,
	0x7F, 0xFE, 0xFC, 0xF8, 0xE0, 0xC0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0xFF, 0,
	0, 128,
	0x00,
	0x7F, 0x3F, 0x3F, 0x1F, 0x8F, 0xCF, 0xE7, 0xF3, 0xF1, 0xF8, 0xFC, 0xFE, 0xFC, 0xF8, 0xF8, 0xE0,
	0xC0, 0x80, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x1F, 0x9F, 0xDF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
	0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x70, 0x78, 0x78, 0x78,
	0x7C, 0x3E, 0x3F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF0,
	0xFF, 0xFF, 0xFF, 0xF0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x01, 0x03, 0x07, 0x1F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x80, 0x00,
	128, 0
};



uint16 crdGetTrack2Length(uint8 * PackedPAN)
{
	uint16 Index;

	for(Index = 0; Index < 19; Index++)
	{
		if( (*(PackedPAN + Index) & 0xF0) == 0xF0 )
			return (Index << 1);			//return (Index x 2)

		if( (*(PackedPAN + Index) & 0x0F) == 0x0F )
			return (Index << 1) + 1;			//return (Index x 2) + 1
	}

	return CRD_TRACK2_MAX_LEN+1;
}


uint8 crdUnpackpan(uint8 *dest, uint8 *src)
{
	uint8 count;

	for(count=0;;)
	{
		dest[count++] = ((*src & 0xf0) >> 4) | 0x30;
		if (count > 36)
			break;

		dest[count++] = (*src++ & 0x0f) | 0x30;
	}

	return(count);
}


uint16 crdGetPANLength(uint8 * BCDPAN)
{
	uint16 Index;
	for(Index = 0; Index < 10; Index++)
	{
		if( (*(BCDPAN + Index) & 0xF0) == 0xD0 )
			return (Index << 1);			//return (Index x 2)


		if( (*(BCDPAN + Index) & 0x0F) == 0x0D )
			return (Index << 1) + 1;			//return (Index x 2) + 1
	}

	return CRD_MAX_PAN_LEN+1;
}

void crdPackTrack2(uint8 *Destination, uint8 * Source, uint16 SourceLength)
{
	uint16 Index;
	memset(Destination, 0xFF, 19);
	for(Index = 0; Index < SourceLength; Index += 2)
		*Destination++ = ((Source[Index] & 0x0f) << 4) | (Source[Index + 1] & 0x0f);
	
	if (SourceLength % 2 != 0)		
		*(--Destination) |= 0x0f;
}


int intTmsGet( stProfile  *profile )
{
	//S_INFOS_RESEAU_SUP sParameters;
	int rc;
	// Get parameters entered from the manager menu.
	//PSQ_Donner_infos_reseau_sup ( &sParameters );
	S_FS_FILE *fh;
	DriveInit();
	fh = FS_open(TMS_SETTING, "r");
	if (fh==NULL)
		return !RET_OK;
	rc=FS_seek(fh, 0, FS_SEEKSET);
	FS_read((byte *)profile,1,sizeof(stProfile),fh);
	FS_close(fh);

	DriveTerm();
	return 0;
}


stProfile  * profile(void)
{
  static stProfile 	profile;

 if (intTmsGet(&profile)==0)
 	return (&profile);

//s     profile.SerialNum
 	 memset((byte *)&profile,0x00,sizeof(stProfile) );
  return NULL;//&profile;
		
  
}

int icentertext(char * text )
{
  int len=strlen(text);
  return (60-((len*5)/2));

	}

void vdDisplay3Line(char * pcTittle, char * pcLine1,char * pcLine2,char * pcLine3)
{

			 FILE *hDisplay;
			     int nFont;
			    int   height;
  				int   width;
   	       int DisplayHeaderStatus;

			hDisplay = fopen("DISPLAY","w");
			nFont = GetDefaultFont();

			DisplayHeaderStatus=StateHeader(0);
			GetScreenSize (&height,&width);
			CreateGraphics(_SMALL_);
			DrawWindowFont  (2,10,125,60,  1,pcTittle,  _SMALL_  ) ;
			_DrawString(pcLine1, icentertext(pcLine1), 25, _OFF_);
			_DrawString(pcLine2, icentertext(pcLine2), 35, _OFF_);
			_DrawString(pcLine3,icentertext(pcLine3) , 45, _OFF_);

			PaintGraphics();
			SetDefaultFont((int)_dSMALL_);

			StateHeader(DisplayHeaderStatus);
			fclose(hDisplay);

		//pp_display_text4(char * tittle, char * prompt1, PT_ALIGN_CENTER, char * prompt2, promptAttrib_t attrib2, char * prompt3, promptAttrib_t attrib3, char * prompt4, promptAttrib_t attrib4)
		

   return ;
} 


void StateHeaders(int st)
{
	int val;
	if (!st)
	{
		if (IsHeader())
			DHeaderStatus=StateHeader(0);	
		
	}
	else
	{
		if (IsHeader())
			return;
		
		val = EventHeader(_ALL_STATE_);
		val = (val ^ _SOCLE_STATE_); /* inhibition of socle state */
		EventHeader(val);
		StateHeader(DHeaderStatus);
	}
}

void InitDefaut(int flag, int offset)
{
    int MAXX;
    int MAXY;

    GetScreenSize(&MAXY, &MAXX);
    Menu.Fenetre.left = 0; /* */
    Menu.Fenetre.top = 0; /* */
    Menu.Fenetre.rigth = (MAXX - 1); /* */
    Menu.Fenetre.bottom = (MAXY - 1); /* */
    Menu.Fenetre.nblines = 4; /* */
    Menu.Fenetre.fontsize = _MEDIUM_; /* */
    Menu.Fenetre.type = _PROPORTIONNEL_; /* */
    Menu.Fenetre.police = 0; /* */
    Menu.Fenetre.correct = flag; /* */
    Menu.Fenetre.offset = offset; /* */
    Menu.Fenetre.shortcommand = _ON_; /* */
    Menu.Fenetre.selected = _OFF_; /* */
    Menu.Fenetre.thickness = 2; /* */
    Menu.Fenetre.border = _ON_; /* */
    Menu.Fenetre.popup = _NOPOPUP_; /* */
    Menu.Fenetre.first = 0; /* */
    Menu.Fenetre.current = 0; /* */
    Menu.Fenetre.time_out = 120;
}

unsigned short GetAppID(e_eventtype eventid)
{ 
	int i, j, k;
	unsigned char cr;
	unsigned short ind[MAX_APP];
	
	BUFFER_SAISIE buf_saisie;
	k=0;
	StateHeaders(0);
	InitDefaut(_ON_, 1);
	memset(&ind,0x00, sizeof(ind));
	for (i=0;i<totapreg.totapp;i++)
	{
		for (j=0;j<50;j++)
		{
			if (totapreg.stap[i].evtsupport[j]==eventid)
			{	
				ind[k]=totapreg.stap[i].apptype;
				Menu.tab[k++]=totapreg.stap[i].appname;				
			}
		}
	}

	
	Menu.Fenetre.titre = "Choose Application\n";
    	Menu.tab[k] = NULL;
		
	if (k==1) //only one application which support the Event		
		return ind[0];

	
    	G_List_Entry(&Menu);
    	ttestall(ENTRY, 0);
    	cr = Read_Saisie(&buf_saisie);
    	//StateHeader(1);
		
    	if (cr == CR_ENTRY_OK)
    	{
        	return  ind[buf_saisie.donnees[0]];
    	}
	
	return 0;
    
}

int is_for_you_before(NO_SEGMENT noappli, S_TRANSIN *param_in, S_ETATOUT    *param_out)
{
	    S_ETATOUT etatout;

   
		_trace("	is_for_you_before");
	    if(param_in->support == CHIP_SUPPORT)	    
	    	{
	    		read_date(&g_date);
			appid_act=GetAppID(EVMSG_EMV_PROC);			
			if (!appid_act)
				return STOP;		
	    	}
		else if (			
			(param_in->support == TRACK2_SUPPORT) ||
			(param_in->support ==TRACK12_SUPPORT) ||
			(param_in->support ==TRACK32_SUPPORT) ||
			(param_in->support ==TRACK123_SUPPORT)
		)
		{
//			_trace("	Magentic");
			appid_act=GetAppID(EVMSG_ASK_MAG_CARD);			
			if (!appid_act)
			{
//				_trace("	No Magentic");
				return STOP;	
			}
	
		}
		memcpy (&etatout, param_out, sizeof(etatout));
		// give my application name 
		strcpy((char *)etatout.returned_state[etatout.response_number].appname,(char *)appname);
		// accept this card 
		etatout.returned_state[etatout.response_number].state.response = 2;
		// give my application number
		etatout.returned_state[etatout.response_number].no_appli = noappli;
		// increment the response number 
		etatout.response_number++;
		memcpy (param_out, &etatout, sizeof(etatout));
	/*
	    memcpy(&etatout, param_out, sizeof(etatout));
		
	    etatout.returned_state[etatout.response_number].state.response = 0;
	    memcpy(param_out, &etatout, sizeof(etatout));
	*/
	    return  FCT_OK;//is_name(noappli, PT_NULL, param_out);
}

int Main_EMVCUST(unsigned int size, StructProcessStep *data)
{
 	unsigned char priority;
	unsigned int  ret_code;
	

	if (!appid_act)
		appid_act=DEFAULT_MAG_APP;
	
	if (ServiceGet(appid_act,data->service,&priority)==0)	
	{

		StateHeaders(0); // disable display header	
		USR_ServiceCall(appid_act,data->service,sizeof(StructProcessStep),data,&ret_code);	
		
		return ret_code;
	}
	
  	return (FCT_OK);
}


 int CallClientEvent(unsigned short AppNo, ST_InterApp* _stinter)
 {
	unsigned char priority;
	unsigned int  ret_code=0;
	
	byte *buff;

	if (!AppNo)
		AppNo=DEFAULT_MAG_APP;


	StateHeaders(0); // disable display header	

	pp_display_clear(0);
	
	if (ServiceGet(AppNo,SERVICE_EVENTMASTER_CALL,&priority)==0)	
	{
		buff=umalloc(sizeof(ST_InterApp)+10);
		memcpy(buff,_stinter,sizeof(ST_InterApp));		
		USR_ServiceCall(AppNo,SERVICE_EVENTMASTER_CALL,sizeof(ST_InterApp),buff, &ret_code);
		memcpy(_stinter,buff,sizeof(ST_InterApp));
		ufree(buff);
	}

	return ret_code;
 }


int ManageMenu( const char *szTitle, int bRadioButtons, int nDefaultChoice, 
				int nItems, const char* Items[] )
{
	FILE *hDisplay;
	//int DisplayHeaderStatus;

	// Menu.
	StructList Menu;
	int nY;
	int nMaxX;
	int nMaxY;

	ENTRY_BUFFER Entry;

	//
	int i;
	int nInput;
	int nReturn;
	
	//
	hDisplay = fopen( "DISPLAY", "w" );

	// Get Screen size.
	GetScreenSize( &nMaxY, &nMaxX );

	// For the menu height of the menu,
	nY = 0;

	//DisplayHeaderStatus=StateHeader(0); // disable display header
	StateHeaders(0);
	if ((nDefaultChoice < 0) || (nDefaultChoice >= nItems))
	{
		nDefaultChoice = 0;
	}

	//
	CreateGraphics(_MEDIUM_);

	//
	memset( &Menu, 0, sizeof(Menu) );
	Menu.MyWindow.left   = 0;
	Menu.MyWindow.top    = nY;
	Menu.MyWindow.rigth  = nMaxX - 1;
	Menu.MyWindow.bottom = nMaxY - 1;
	if( nMaxY == 128 )
	{
		Menu.MyWindow.nblines = 10;
	}
	else
	{
		Menu.MyWindow.nblines = 5;
	}

	Menu.MyWindow.fontsize		= _MEDIUM_;
	Menu.MyWindow.type			= _PROPORTIONNEL_;
	Menu.MyWindow.font			= 0;
	Menu.MyWindow.correct			= _ON_;
	Menu.MyWindow.offset			= 0;
	Menu.MyWindow.shortcommand	= _ON_;
	if( bRadioButtons )
	{
		Menu.MyWindow.selected = _ON_;
	}
	else
	{
		Menu.MyWindow.selected = _OFF_;
	}

	Menu.MyWindow.thickness		= 2;
	Menu.MyWindow.border		= _ON_;
	Menu.MyWindow.popup			= _NOPOPUP_;
	Menu.MyWindow.first			= nDefaultChoice;
	Menu.MyWindow.current		= nDefaultChoice;
	Menu.MyWindow.time_out		= 60;
	Menu.MyWindow.title			= (unsigned char*)szTitle;

	for( i = 0; i < nItems; i++ )
	{
		Menu.tab[i] = (unsigned char*)Items[i];
	}

	G_List_Entry((void*)&Menu);
	ttestall(ENTRY, 0);
	nInput = Get_Entry((void*)&Entry);

	switch( nInput )
	{
	case CR_ENTRY_OK:
		nReturn = Entry.d_entry[0];
		break;

	case CR_ENTRY_NOK:
		nReturn = __EXIT_KEY;
		break;

	default:
		nReturn = __BACK_KEY;
		break;
	}
	//StateHeader(DisplayHeaderStatus); // move display header in previous state
	fclose( hDisplay );
	
	return nReturn;
}

#ifdef APP_ECR
int DriveInit()

{
    
  //   * Initialise the interface.
  //   * Store the application identification and version information
  //   * passed in <ApplVers>.
  //   * Return 0 in case of no error or value < 0 otherwise.
  //   *
    
    S_FS_PARAM_CREATE ParamCreat;
    int rc;	
    long DiskSize;
    FILE *	hDisplay;

	
    hDisplay=fopen("DISPLAY","w");
    			
    ParamCreat.Mode=FS_WRITEONCE;	
    rc=FS_mount("/"LDISK,&ParamCreat.Mode);
    switch(rc)
    {
    	
    	case FS_NOFORMAT:
		_clrscr();	
    		DrawString("PERFORMING FORMAT DISK...",1,0,_OFF_);
		ttestall(0, 50);
		FS_format("/"LDISK,FS_WRTMOD,10);	 
		rc=FS_mount("/"LDISK,&ParamCreat.Mode);		
	case FS_OK:
		rc= ERR_NONE;
		break;
	case FS_KO:	
			_clrscr();	
			DiskSize = 8192;
			strcpy( ParamCreat.Label, LDISK );
//			ParamCreat.Mode			= FS_WRITEONCE;
			ParamCreat.AccessMode	= FS_WRTMOD;
			ParamCreat.NbFichierMax = 10;
			ParamCreat.IdentZone	= FS_WO_ZONE_DATA;
			rc = FS_dskcreate( &ParamCreat, &DiskSize );
			if ( rc == FS_OK )
			{
				DrawString("Creating Disk OK...",1,0,_OFF_);				
				ttestall(0, 20);
				rc=FS_format("/"LDISK , FS_WRTMOD, 20);
				if (rc!=FS_OK)
				{	
					_clrscr();
					DrawString("Format KO...",1,0,_OFF_);	
					DrawString("Strike a Key",2,0,_OFF_);
					ttestall(KEYBOARD, 0);
					rc= !RET_OK;
				}

				  ParamCreat.Mode=FS_WRITEONCE;	
    			  	  rc=FS_mount("/"LDISK,&ParamCreat.Mode);
				  rc= ERR_NONE;
			}
			else
			{ 
				_clrscr();
				DrawString("Creating Disk KO...",1,0,_OFF_);	
				DrawString("Strike a Key...",2,0,_OFF_);					
				ttestall(KEYBOARD, 0);
				rc= !RET_OK;
			}
			
		break;
     }

    fclose(hDisplay);
    return rc;
}

void DriveTerm(void)

{
    
    // * Release all allocated resources and quit processing of this API.
    // *
    
     FS_unmount("/"LDISK);
}

int GetSetting( mastersetting_t *mstset )
{
	//S_INFOS_RESEAU_SUP sParameters;
	int rc;
	// Get parameters entered from the manager menu.
	//PSQ_Donner_infos_reseau_sup ( &sParameters );
	S_FS_FILE *fh;
	DriveInit();
	fh = FS_open(FN_SETTING, "r");
	if (fh==NULL)
		return !RET_OK;
	rc=FS_seek(fh, 0, FS_SEEKSET);
	FS_read((byte*)mstset,1,sizeof(mastersetting_t),fh);
	FS_close(fh);
	_trace("COMM %u %u ==%u",COM0, COM5,mstset->coms);
	DriveTerm();
	return ERR_NONE;
}
void SetSetting( mastersetting_t mstset )
{
	int rc;
	// Get parameters entered from the manager menu.
	//PSQ_Donner_infos_reseau_sup ( &sParameters );
	S_FS_FILE *fh;
	DriveInit();
	 fh = FS_open(FN_SETTING, "w");
	if (fh==NULL)
	{
		FS_unlink(FN_SETTING);
		fh = FS_open(FN_SETTING, "a");
		if (!fh)
			return;
	}
	rc=FS_seek(fh, 0, FS_SEEKSET);
	FS_write((byte*)&mstset,1,sizeof(mastersetting_t),fh);
	FS_close(fh);
	
	DriveTerm();	
}
uint8 ComECRSetting(void)
{
	int i;
	unsigned char cr;
	//unsigned short ind[MAX_APP];
      unsigned long ulComm=0;

	char *const COMECRSet[]=
		{
			"COM 0",
			"USB",
		};
		
	BUFFER_SAISIE buf_saisie;
	

	StateHeaders(0);
	InitDefaut(_ON_, 1);
		
	for (i=0;i<2;i++)
		Menu.tab[i]=COMECRSet[i];				
	


	Menu.Fenetre.titre = "COM ECR:\n";
    	Menu.tab[i] = NULL;		

    	G_List_Entry(&Menu);
    	ttestall(ENTRY, 0);
    	cr = Read_Saisie(&buf_saisie);    
		
		ulComm=mstset.coms;
		
    	if (cr == CR_ENTRY_OK)
    	{    	
    		//mstset.coms=buf_saisie.donnees[0];
    		if(buf_saisie.donnees[0] == 0)
	    		mstset.coms=COM0;
		else if(buf_saisie.donnees[1] == 0)// imam Fix For Menu 
			mstset.coms=COM5;
          // _trace("Test %u=%u=%u",buf_saisie.donnees[0],mstset.coms ,buf_saisie.donnees[1]);
		   
    		SetSetting(mstset);

		 // we must Restart Do Init ECR can Be Done 
		if (ulComm!=mstset.coms)// only if user set Another Setting 
			{
			pp_display_clear(0);
			pp_display_text(1, 0, "PLEASE WAIT ", PT_ALIGN_CENTER|PT_CLEAR);
			pp_display_text(2, 0, "RESTART EDC", PT_ALIGN_CENTER|PT_CLEAR);
			pp_display_text(3, 0, "FOR ECR", PT_ALIGN_CENTER|PT_CLEAR);
			pp_beep(1);
			ttestall(0,500);
				
			exit(0);
		}
		 // 
    	}
	
	return 0;
}

#endif

int more_function( NO_SEGMENT no, void *p1, void *p2 )
{

	int bContinue = 1;
	do
	{
		switch( ManageMenu( "PINPAD", 0, 0, NUMBER_OF_ITEMS(MasterMenu), MasterMenu ))
		{
		case 0:
			pp_open_hmi();
			StateHeaders(0);
			pp_display_clear(0);
			pp_display_text4("ABOUT PINPAD", 
				NULL, 0, 
				dpmThisApplicationName(), PT_ALIGN_LEFT | PT_CLEAR, 
				"BNI PINPAD", PT_ALIGN_LEFT | PT_CLEAR, 
				//"v1.0.1 D20080811", PT_ALIGN_LEFT | PT_CLEAR);
				"V.02.iPP-13082012", PT_ALIGN_LEFT | PT_CLEAR);//v2.1.0 D20081028 -> new(v2.1.1 29 June 2010)
			pp_ttestall(KEYBOARD, 15*100);
			//StateHeader(1);
			pp_close_hmi();
			bContinue = 0;
			break;

#if 0 //def APP_ECR
		case 1:		
			pp_open_hmi();
			ComECRSetting();
			pp_close_hmi();
			bContinue = 0;
			break;
#endif
/*
		case 2:		
			break;
*/
		default:
			bContinue = 0;
			break;
		}
	}
	while( bContinue == 1 );

	return FCT_OK;
}



#define LABEL_DISK   "HOST"
#define TAILLE_DISK				0x19000

int CUDISK_CreateDisk(void)
{
    int Retour;
    unsigned long TailleDisk;
    S_FS_PARAM_CREATE ParamCreat;
    char FilePath_L[33];

    ParamCreat.Mode = FS_WRITEONCE;
    ParamCreat.IdentZone = FS_WO_ZONE_DATA;
    strcpy(ParamCreat.Label, LABEL_DISK);
    ParamCreat.AccessMode = FS_WRTMOD;
    ParamCreat.NbFichierMax = 30;
    TailleDisk = TAILLE_DISK;

    sprintf(FilePath_L, "/%s", LABEL_DISK);
    Retour = FS_mount(FilePath_L, &ParamCreat.Mode);
    if (Retour != FS_OK)
    {
        Retour = FS_dskcreate(&ParamCreat, &TailleDisk);
    }
    return (Retour);
}

int after_reset( NO_SEGMENT no, void *p1, S_TRANSOUT *etatseq )
{		
	animFlag = 0;	
	StateHeaders(1);
	getTerminalType();
//	   raz_init(noappli);
    CUDISK_CreateDisk();
#ifdef APP_ECR
	initECR(no);
#endif	
   //  profile()
	return FCT_OK;
}

int is_state(NO_SEGMENT no,void *p1,S_ETATOUT *etatseq)
{
	S_ETATOUT etatout;
	int retour;
	//StateHeaders(1);
	memcpy (&etatout, etatseq, sizeof(etatout));
	etatout.returned_state[etatout.response_number].state.response = REP_OK;
	memcpy (etatseq, &etatout, sizeof(etatout));
	retour = is_name (no, PT_NULL, etatseq);
	return (retour);
}

int is_name(NO_SEGMENT no,void *p1,S_ETATOUT *etatseq)
{
	S_ETATOUT etatout;
	
	StateHeaders(1);
	pp_display_adjust(TRUE);
	memcpy ((char *)&etatout, (char *)etatseq, sizeof(etatout));
	strcpy((char *)etatout.returned_state[etatout.response_number].appname,(char *)appname);
	etatout.returned_state[etatout.response_number].no_appli = no;
	etatout.response_number++;
	memcpy (etatseq, &etatout, sizeof(etatout));
	
#ifdef APP_ECR
	if (combuf.len && com_is_busy)
	{
	_trace( "SEND TO 2ND APP" );
		int ret;
		//FILE *handles;
		FILE * Cam01, Cam02;
		
		Cam01 = stdperif("CAM0", &Cam02);

		if (Cam01)
			fclose(Cam01);

		ret=ECR_CallService(0, combuf.data, &combuf.len, COMECR_STR);

/*handled in credit app
		if (ret)
		{
			combuf.len=combuf.len;
		}

		handles=fopen(COMECR_STR,"rw");
		format(COMECR_STR,CBR_115200,8,1,NO_PARITY,NO_PARITY,0);
		mask_event (handles , COM_REC_NOT_EMPTY );
				
		send_receive(handles, ON, ON);
		reset_buf(handles,_receive_id);
		reset_buf(handles,_send_id);
		
		fwrite(combuf.data,1,combuf.len,handles);
		//clear all data 
		fread(combuf.data,1,512,handles);
			
		fclose(handles);
*/	
      _trace4("Out name ");
		combuf.len=0;
		com_is_busy=FALSE;
	}	
#endif

	return (FCT_OK);
}

int give_your_domain(NO_SEGMENT no,void *p1,S_INITPARAMOUT *param_out)
{
	S_INITPARAMOUT etatout;
	
	//StateHeaders(1);
	memcpy (&etatout, param_out, sizeof(etatout));
	etatout.returned_state[etatout.response_number].mask     = MSK_MDP|MSK_SWIPE|MSK_TYPE_PPAD|MSK_PINPAD|MSK_STANDARD|MSK_LANGUE|MSK_FRMT_DATE|MSK_DATE;
	etatout.returned_state[etatout.response_number].application_type = TYP_EXPORT;
	etatout.response_number++;
	memcpy (param_out, &etatout, sizeof(etatout));
	return (FCT_OK);
}

int is_delete(NO_SEGMENT no,void *paramin,S_DELETE *paramout)
{
	paramout->deleting=DEL_YES;

	//StateHeaders(1);
	return (FCT_OK);
}

int state (NO_SEGMENT noappli,void *p1,void *p2)
{
	return FCT_OK;
}


int mcall (NO_SEGMENT noappli,void *p1,void *p2)
{
	//StateHeaders(1);
	return FCT_OK;
}

int consult (NO_SEGMENT noappli,void *p1,void *p2)
{
	//StateHeaders(1);
	return FCT_OK;
}

int time_function (NO_SEGMENT noappli,void *p1,void *p2)
{	
	//StateHeaders(1);
	return (FCT_OK);
}

#if 0
int keyboard_event(NO_SEGMENT noappli,S_KEY *p1,S_KEY *p2)
{
	S_KEY keyA, keyB;
	ST_InterApp st_it;		
	
//	int ind=-1;
	memcpy(&keyA,p1,sizeof(keyA));
	memcpy(&keyB,p2,sizeof(keyB));

	pp_set_frame(FALSE);
	_trace("MASTER : keycode %d", keyA.keycode);
	switch (keyA.keycode)
	{	
	case N0:		
	case N1: 		
	case N8: 
	case N9: 
	case T_VAL :
		//keyB.keycode = keyA.keycode;
		keyB.keycode = NAVI_CLEAR;
		//keyA.keycode = 0;
		break;
	case T_POINT : 
		// inhibits these keys for International domain
		       appid_act=GetAppID(EVMSG_FUNCTION);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_FUNCTION;
				st_it.no=0;				
				
				CallClientEvent(appid_act,&st_it);						
			}
		keyB.keycode = 0 ; 
		break; 
//Handled for Manual entry		
	case N2:		
	case N3: 
	case N4: 
	case N5: 
	case N6: 		
	case N7:		
	case F1:
	case F2:
	case F3:
	case F4:
		// inhibits these keys for International domain
		       appid_act=GetAppID(EVMSG_IDLE_APP);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_IDLE_APP;
				st_it.no=keyA.keycode;				
				
				CallClientEvent(appid_act,&st_it);						
			}
		keyB.keycode = 0 ; 
		break; 
//aan, 11 08 2008
//	case UP:
	case T_SKHAUT:
		_trace("UP Enter");
//	case DOWN:
		// inhibits these keys for International domain
		       appid_act=GetAppID(EVMSG_IDLE_APP);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_IDLE_APP;
				st_it.no=keyA.keycode;				
				
				CallClientEvent(appid_act,&st_it);						
			}
		keyB.keycode = 0 ; 
		break;
//end of aan
	case T_CORR :
	case T_ANN : 
	case NAVI_CLEAR : 
	case NAVI_OK : 
//	case UP : 
	case DOWN : // return the same key value for keys above ! 
	case T_F :  // do not filter F key and return the same key ! 

		if (keyA.keycode==T_F)
		{
			char pwdBuf[6];
			memset(pwdBuf, 0, sizeof(pwdBuf));
			pp_open_hmi();
			StateHeaders(0);

			pp_display_clear(0);
			pp_display_text(2, 0, "SECURITY CODE ?", PT_ALIGN_LEFT | PT_CLEAR);
			//if(IsPasswordOK(prtSecurityCode, PASS_SECURITY_CODE, 6) != SUCCESS)
			if(PasswordEntry(pwdBuf, 3, 10, 6, 6, TRUE, 30)==0)
				keyA.keycode=NAVI_CLEAR;
			else
				{
				if(memcmp(pwdBuf,"328926", 6)!=0)
					{
					pp_beep(3);
					pp_display_text(3, 0, "INVALID CODE", PT_ALIGN_CENTER | PT_CLEAR);
					keyA.keycode=NAVI_CLEAR;	
					}
				}
			//StateHeader(1);
			
			pp_close_hmi();
		}
	
		keyB.keycode = keyA.keycode;  
		break; 
	}
	memcpy(p2,&keyB,sizeof(keyB));
	return (FCT_OK);
}

#else

int keyboard_event(NO_SEGMENT noappli,S_KEY *p1,S_KEY *p2)
{
		S_KEY keyA, keyB;
//	ST_InterApp st_it;
// imam add for ICT 	
 uint8 tertype2;
///////////////
S_EQUIPEMENT Equipment;

	memset(&Equipment, 0x00, sizeof (S_EQUIPEMENT));
	PSQ_Donner_reference(&Equipment);
	tertype2= Equipment.mod_equip[1];	
///////////////
	
//	int ind=-1;
	memcpy(&keyA,p1,sizeof(keyA));
	memcpy(&keyB,p2,sizeof(keyB));

	
	pp_set_frame(FALSE);

	if (tertype2==48) // ICT220
	    {	if (keyA.keycode==36)
			keyA.keycode=F2;
		 else if (keyA.keycode==35)
			keyA.keycode=F3;
		}

	switch (keyA.keycode)
	{	
	case N0:		
	case N1: 		
	case N8: 
	case N9: 
	case T_VAL :
		//keyB.keycode = keyA.keycode;
		keyB.keycode = NAVI_CLEAR;
		//keyA.keycode = 0;
		break;
	case T_POINT : 
		// inhibits these keys for International domain
		 #if 0
		       appid_act=GetAppID(EVMSG_FUNCTION);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_FUNCTION;
				st_it.no=0;				
				
				CallClientEvent(appid_act,&st_it);						
			}
			#endif
		keyB.keycode = 0 ; 
		break; 
//Handled for Manual entry		
	case N2:		
	case N3: 
	case N4: 
	case N5: 
	case N6: 		
	case N7:
		
	case F1:
	case F2:
	case F3:
	case F4:
		// inhibits these keys for International domain
		#if 0
		       appid_act=GetAppID(EVMSG_IDLE_APP);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_IDLE_APP;
				st_it.no=keyA.keycode;				
				
				CallClientEvent(appid_act,&st_it);						
			}
			#endif
		keyB.keycode = 0 ; 
		break; 
/*		
	case F1 : 	
	case F2 : 
	case F3 : 
	case F4 : 
		{
			switch(keyA.keycode)
			{
			case F1:
				ind=0;break;
			case F2:
				ind=1;break;
			case F3:
				ind=2;break;	
			case F4:
				ind=4;break;
			}
			
			if (ind<totapreg.totapp)
			{				
				ST_InterApp st_it;		
				
				st_it.serviceid=EVMSG_IDLE_APP;
				st_it.no=0;
				
				_trace("EVMSG_IDLE_APP");				
				CallClientEvent(totapreg.stap[ind].apptype,&st_it);
				appid_act=totapreg.stap[ind].apptype;
				keyB.keycode =NAVI_CLEAR;
				_trace("EVMSG_IDLE_APP SUCCESS");
			}		
				
		}
		break;
*/

//aan, 11 08 2008
	case UP:
	case DOWN:
		#if 0
		// inhibits these keys for International domain
		       appid_act=GetAppID(EVMSG_IDLE_APP);			
			if (appid_act)
			{				
				st_it.serviceid= EVMSG_IDLE_APP;
				st_it.no=keyA.keycode;				
				
				CallClientEvent(appid_act,&st_it);						
			}
			#endif
		keyB.keycode = 0 ; 
		break;
//end of aan
	case T_CORR :
	case T_ANN : 
	case NAVI_CLEAR : 
	case NAVI_OK : 
//	case UP : 
//	case DOWN : // return the same key value for keys above !
	case T_F :  // do not filter F key and return the same key ! 

		if (keyA.keycode==T_F)
		{
			char pwdBuf[6];
			memset(pwdBuf, 0, sizeof(pwdBuf));
			pp_open_hmi();
			StateHeaders(0);

			pp_display_clear(0);
			 pp_settittle("PINPAD");
			pp_display_text(2, 0, "SECURITY CODE ?", PT_ALIGN_LEFT | PT_CLEAR);
			//if(IsPasswordOK(prtSecurityCode, PASS_SECURITY_CODE, 6) != SUCCESS)
#ifdef 		_PASS_GEN_	
			   //if (
			if (   GetSecurityKey()==STOP)

	//		   	int GetSecurityKey()==STOP)
			   	{
			   	pp_beep(3);
				pp_display_text(3, 0, "INVALID CODE", PT_ALIGN_CENTER | PT_CLEAR);
				pp_close_hmi();
				keyA.keycode=NAVI_CLEAR;
				keyB.keycode = keyA.keycode;  
				memcpy(p2,&keyB,sizeof(keyB));
			   return FCT_OK;
			   	
			   
			
			   	 }
				//	return FCT_OK;
#else			   
			if(PasswordEntry(pwdBuf, 3, 10, 6, 6, TRUE, 30)==0)
				keyA.keycode=NAVI_CLEAR;
			else
				{
				if(memcmp(pwdBuf,"328926", 6)!=0)
					{
					pp_beep(3);
					pp_display_text(3, 0, "INVALID CODE", PT_ALIGN_CENTER | PT_CLEAR);
					ExecutM();// imam 
					keyA.keycode=NAVI_CLEAR;
					//_trace4
					}
				}
			//StateHeader(1);
#endif	

			pp_close_hmi();
		}
	
		keyB.keycode = keyA.keycode;  
		break; 
	}
	memcpy(p2,&keyB,sizeof(keyB));
	return (FCT_OK);
}

#endif

int file_received(NO_SEGMENT no,S_FILE * param_in,void *p2)
{

	S_FS_PARAM_CREATE ParamCreat;
	int		 Retour;
	char		 Dir_File[25];
	char		 Dir_Label[25];
	S_FS_FILE      *pFile;
	
	memclr(Dir_File,sizeof(Dir_File));
	memclr(Dir_Label,sizeof(Dir_Label));
	
	sprintf(Dir_Label,"/%s",param_in->volume_name);
	ParamCreat.Mode = FS_WRITEONCE;
	Retour = FS_mount (Dir_Label,&ParamCreat.Mode);
	if (Retour == FS_OK)
	{
		sprintf(Dir_File,"/%s/%s",param_in->volume_name,param_in->file_name);
		// the file can be open at this stage
		pFile = FS_open (Dir_File, "r");
		// read the file and get parameters 
		FS_close(pFile);
		// cannot be deleted as it is located in system disk 
		FS_unmount(Dir_Label);
	}

	return (FCT_OK);
}



int is_evol_pg(NO_SEGMENT noappli, void *p1, S_ETATOUT *param_out)
{
	S_ETATOUT etatout;
	int       retour;
	//StateHeaders(1);
	memcpy(&etatout, param_out, sizeof(etatout));
	etatout.returned_state[etatout.response_number].state.response=REP_OK;
	memcpy(param_out,&etatout,sizeof(etatout));
	retour = is_name (noappli, PT_NULL, param_out);
	return(FCT_OK);		 
}

int is_time_function(NO_SEGMENT noappli, void *p1, S_ETATOUT *param_out)
{
	S_ETATOUT etatout;
	int       retour;
	
	memcpy(&etatout, param_out, sizeof(etatout));
	etatout.returned_state[etatout.response_number].state.response=REP_OK;
	memcpy(param_out,&etatout,sizeof(etatout));
	retour = is_name (noappli, PT_NULL, param_out);
	return(FCT_OK);		 
}


int is_change_init(NO_SEGMENT noappli, void *p1, S_ETATOUT *param_out)
{
	S_ETATOUT etatout;
	int       retour;
	memcpy(&etatout, param_out, sizeof(etatout));
	// accept all 
	etatout.returned_state[etatout.response_number].state.mask=0;
	memcpy(param_out,&etatout,sizeof(etatout));
	retour = is_name (noappli, PT_NULL, param_out);
	return(FCT_OK);		 
}

int modif_param(NO_SEGMENT noappli, S_MODIF_P *param_in, void *p2)
{
	S_MODIF_P param_changed;
	
	memcpy(&param_changed, param_in,sizeof(param_changed));	
	return(FCT_OK);
}



int is_for_you_after(NO_SEGMENT no, S_TRANSIN *param_in, S_CARDOUT *param_out)
{
#if 0
	S_CARDOUT card_out;
    	S_ETATOUT etatout;

	 _trace("is_for_you_after");		
	    etatout.response_number = 0;
	    is_name(no, NULL, &etatout);

	   
	    /* Card recognised only when mag stripe is used       
	    */
	    memcpy(&card_out, param_out, sizeof(card_out));
	    if ((param_in->support == TRACK2_SUPPORT) || (param_in->support ==
	        TRACK12_SUPPORT) || (param_in->support == TRACK32_SUPPORT))
	    {
	    	strcpy(card_out.returned_state[card_out.response_number].appname,
            (char*)etatout.returned_state[0].appname);
        	card_out.returned_state[card_out.response_number].no_appli = no;
        	card_out.returned_state[card_out.response_number].cardappnumber = 1;
        	card_out.returned_state[card_out.response_number].cardapp[0].priority =
            		10; //30;
        	strcpy(card_out.returned_state[card_out.response_number].cardapp[0].cardappname, (char*)etatout.returned_state[0].appname);
        card_out.response_number++;
		
	     	//memcpy(&card_out, param_out, sizeof(card_out));		
	        //card_out.returned_state[card_out.response_number].cardappnumber = 0;
	            //refuse to process the card
	        //card_out.returned_state[card_out.response_number].cardapp[0].priority =  0;
		 //memcpy(param_out, &card_out, sizeof(card_out));		
//		  _trace("is_for_you_after Mag");	
	    }
	    else
	    {
	        /* This is a Chip card            */	
	      	int ret_code=FCT_OK;			
		ST_InterApp st_it;

// select EMV Application
		_trace("	is_for_you_after ini Chip mas");
#if 0
		appid_act=GetAppID(EVMSG_ISFORYOUAFTER);			
		if (!appid_act)
		{
			return STOP;	
		}
#endif
		st_it.serviceid=EVMSG_ISFORYOUAFTER;
		st_it.no=no;
		
		memcpy(&(st_it.par_in.in_for_you_after), param_in, sizeof(S_TRANSIN));	
		ret_code= CallClientEvent(appid_act,&st_it); 				
		memcpy(param_out, &(st_it.par_out.out_for_you_after), sizeof(S_CARDOUT));
		
		return ret_code;
	    }
	   
#endif
	 return (FCT_OK);

}

int debit_non_emv (NO_SEGMENT no, S_TRANSIN * param_in, S_TRANSOUT * param_out)
{
#if 0
	int len,i, ret_code;	
	ST_InterApp st_it;
	
	st_it.par_out.out_debitnonemv=FALSE;
	st_it.ins_date=g_date;
	_trace("MASTER : debit_non_emv ");
	StateHeaders(0);
	switch(param_in->support)
	{
	case CHIP_SUPPORT ://3			
	_trace("MASTER : CHIP SUPPORT");
		break;
	case TRACK12_SUPPORT:	//1
	case TRACK32_SUPPORT:	//2
	case TRACK2_SUPPORT:	//0
	case TRACK123_SUPPORT:	//6	
		//pp_display_adjust(FALSE);
		len=strlen(param_in->track2);
		for (i=0;i<len;i++)
		{
			if (param_in->track2[i]=='D')
				param_in->track2[i]='=';
		}
		

		st_it.serviceid=EVMSG_ASK_MAG_CARD;
		st_it.no=no;	

		_trace("MASTER : MAGNETIC, no = %d --- serviceid = %d", st_it.no, st_it.serviceid);
		memcpy(&(st_it.par_in.in_debitnonemv), param_in, sizeof(S_TRANSIN));	
		appid_act=GetAppID(EVMSG_ASK_MAG_CARD);	//nazar, add on application must be selected first					
		ret_code= CallClientEvent(appid_act,&st_it); 				
		break;
	case OPERATOR_SUPPORT ://4
	case UNKNOWN_SUPPORT:
	case CLESS_SUPPORT:	
		_trace("MASTER : OTHER  SUPPORT");
		break;
	}

	//pp_close_hmi();
	param_out->noappli      = no;
	param_out->rc_payment  = PAY_OK;
#endif
	return (FCT_OK);
}


int select_aid_extended(NO_SEGMENT noappli, S_SELECT_AID_EXTENDED *param_in,  S_AID_OUT *param_out)
{
	int ret_code;
	ST_InterApp st_it;
	StateHeaders(0);
	st_it.serviceid=EVMSG_EMV_SELECT_AID_EXT;
	st_it.no=noappli;
	_trace("select_aid_extended");
	memcpy(&st_it.par_in.in_select_aid_extended, param_in, sizeof(S_SELECT_AID_EXTENDED));
	ret_code= CallClientEvent(appid_act,&st_it);
	memcpy(param_out, &st_it.par_out.out_select_aid_extended, sizeof(S_AID_OUT));
	return ret_code;
}

int select_aid(NO_SEGMENT no, S_SELECT_AID *param_in, S_AID_OUT *param_out)
{
	int ret_code;
	ST_InterApp st_it;
	StateHeaders(0);
	st_it.serviceid=EVMSG_EMV_SELECT_AID;
	st_it.no=no;
	_trace("select_aid");
	memcpy(&(st_it.par_in.in_select_aid), param_in, sizeof(S_SELECT_AID));	
	ret_code= CallClientEvent(appid_act,&st_it); 
	memcpy(param_out, &(st_it.par_out.out_select_aid_extended), sizeof(S_AID_OUT));
	return ret_code;
	
	//return FCT_OK;//CallClientEvent(appid_act,EVMSG_EMV_SELECT_AID,param_in,param_out, no);	
}


uint8 xx_peripheral_read(peripread * pTag)
{
	/* data */
	FILE *swipe2, *swipe1 ;
//	FILE *hCam0 = NULL;
	unsigned short int peripheral ;
	int cr_iso2=0;
	int cr_iso1=0 ;
	unsigned char swipeState = 0;	//aan, 28 Juli 2007, 
	unsigned int periphEvent1=0;
	unsigned int periphEvent2=0;

 int Timeout =0;
 int counter =25;

#ifdef __AAN_SWIPE_LATER__1
	unsigned char possibilityNoTrack1;
	unsigned char swipeStatus = 0;
	possibilityNoTrack1 = 0x00;
#endif

	/* open card reader files */
	swipe2 = fopen ( "SWIPE2","r*") ;
	if (!swipe2)
		return prTrackError;
	
	swipe1 = fopen ( "SWIPE31", "r*") ;

	 periphEvent1 = periphEvent1|KEYBOARD|SWIPE31 | SWIPE2;
	 periphEvent2 = periphEvent2|SWIPE31|SWIPE2 ;

    Timeout= 25;//atoi(profile()->timeSwipe);
	
	
	do
		{

	/* wait for both readers */
	//peripheral = ttestall ( KEYBOARD|SWIPE31 | SWIPE2, 500 ) ;
	peripheral = ttestall ( periphEvent1, 100) ; // imam 
	
//	peripheral = ttestall ( periphEvent1, (TIMEOUT_T-5) * 100) ;
	peripheral |= ttestall ( peripheral ^ ( periphEvent2) , 1 ) ;

#ifdef __AAN_SWIPE_LATER__1
	status(swipe2, &swipeStatus);
	if(swipeStatus == TRACK_READ)//track2 support (hore, kebaca-kebaca)
		possibilityNoTrack1 |= TRACK2_EXIST;
	status(swipe1, &swipeStatus);
	if(swipeStatus == TRACK_READ)//track1 support (hore, kebaca-kebaca)
		possibilityNoTrack1 |= TRACK1_EXIST;
#endif

	pTag->errocode=prTimeOut;
	
	if (peripheral & KEYBOARD)
	{
		pTag->errocode=prKeyPressed;
		pTag->pValue=(uint8)pp_get_key(0);//getchar();
	}
	
	else
	{
		if ( peripheral & SWIPE2 )
		{
			pTag->errocode=prReadTrack2;
			peripheral &= ~SWIPE2 ;
			memset(pTag->track2,0x00,sizeof(pTag->track2));
			cr_iso2 = is_iso2 ( swipe2, &pTag->lengthtrack2, pTag->track2) ;

			pTag->lengthtrack2 = (uint8)strlen(pTag->track2);


#ifdef __AAN_SWIPE_LATER__1
			{
			uint8 i;
			uint8 lengthTrack2;
			uint8 track2[128];
			uint8 packTrack2[19];
			
			memset(track2, 0x00, sizeof(track2));
			memset(packTrack2,0x00, sizeof(packTrack2));
			
			lengthTrack2 = pTag->lengthtrack2;
			memcpy(track2, pTag->track2, lengthTrack2);
			for (i=0;i < lengthTrack2; i++)
				{
					if (track2[i]=='D')
						track2[i]='=';
				}
				
			if(cr_iso2 != ISO_OK)
				{
				
				/*if(cr_iso2 == DEF_LUH)
					{
					crdPackTrack2(packTrack2, (uint8 *)&track2[1], (uint16)(lengthTrack2-3));// -3, remove B, F, n LRC
					if (dpmIssuerRecordGet(
						dpmIssuerIDGetByCardID(TransactionData.Iso.Flags.DBSelected, 
						dpmCardRangeIDGetByPAN(packTrack2, 
						(uint8)crdGetPANLength(packTrack2))))->DoMod10 == TRUE)//if false ignore LUHN Failure
						{
							pTag->errocode=prTrackError;
						}
					else
						cr_iso2=ISO_OK;
					}
				else*/
					pTag->errocode=prTrackError;
				}
				
			}
#else
			if (cr_iso2!=ISO_OK)
	#ifdef __AAN_SWIPE_LATER__2
				if(cr_iso2 != DEF_LUH)
	#else
				pTag->errocode=prTrackError;
	#endif
#endif
			
				
		}
		
		if ( peripheral & SWIPE31 )
		{
			pTag->errocode=prReadTrack1;
			peripheral &= ~SWIPE31 ;		
			memset(pTag->track1,0x00,sizeof(pTag->track1));
			cr_iso1 = is_iso1 (swipe1, &pTag->lengthtrack1,pTag->track1) ;
			if (cr_iso1!=ISO_OK)
				pTag->errocode=prTrackError;
			
			swipeState = 2;//
		}
		
#ifdef __AAN_SWIPE_LATER__1
		else if(!(possibilityNoTrack1 & TRACK1_EXIST))
			{
			cr_iso1 = ISO_OK;
			swipeState++;
		#ifdef 	IMAM_ONLY_1
				pTag->errocode=prTrackError;
		swipeState++;
		
		#endif
			
			}
#endif

		if ((!cr_iso2) && (!cr_iso1))
			pTag->errocode=prTrackRead;

		if((swipeState == 1)&&(pTag->errocode==prTrackRead))
			{

			#ifdef IMAM_ONLY_1
			cr_iso1 = ISO_OK;
			swipeState++;

			#endif
	#if 0		
	//		prompt_t	prmpt[4+1];
			//untuk track1 kalau kosong, re-swipe
//			memset(prmpt, 0x00, sizeof(prmpt));

			pp_display_clear(0);
#if 0
			strcpy(CommonMsg[0], "AGAIN, PLEASE..");
			//strcpy(CommonMsg[1], "AGAIN");
			prmpt[0].index = PI_EOF;
			prmpt[0].attrib = PT_ALIGN_CENTER | PT_CLEAR;
			prmpt[2].index = COMMON_MSG_DEF+0;
			prmpt[2].attrib = PT_ALIGN_CENTER | PT_CLEAR;
			prmpt[1].index = PI_TXN_SWIPE_CARD;
			prmpt[1].attrib = PT_ALIGN_CENTER | PT_CLEAR;
			
			pp_display_prompts((prompt_t const*)prmpt);
#endif
			vdDisplay3Line("SWIPE..", "PLEASE","SWIPE ","AGAIN.");
	#endif
			//swipeState = 2;// untuk AMEX
			}
		
	}
	counter--;

	if (counter==0)
		{
		  break;
		}

		}while( 
				(swipeState < 2)
				&& (pTag->errocode == prTrackRead)
				);
	
	fclose(swipe1);
	fclose(swipe2);
	swipe1=NULL;
	swipe2=NULL;
#if 0
	//if(nvmGlobalCurrentEntryModeGet() != ENTRY_FALLBACK)
	{
		fclose(hCam0);
		hCam0=NULL;
	}
#endif
	return pTag->errocode;
}


void dsppin(int t)
{

   pp_display_clear(0);
    pp_settittle("PINPAD");
   if (t==0)
  vdDisplay3Line("ERR", "","CANCELL","");
   else if (t==1)
   vdDisplay3Line("ERR", "","TIMEOUT","");
else if (t==2)
  vdDisplay3Line("ERR", "CARD","FAILED","");
	
	pp_beep(3);
	ttestall(0,100);
		
}



void SendResponseToEcr(unsigned char * ucBuffout, unsigned int len)
{
	FILE *handles;
	FILE * Com1, Com2;
	char ecr_com[6];
	#ifdef NO_PINPAD
	if(GetSetting(&mstset)!=RET_OK)//unable to read the setting, set default to COM0 for ECR comm
		mstset.coms = COM0;

	#else
	if(GetSetting(&mstset)!=RET_OK)//unable to read the setting, set default to COM0 for ECR comm
		mstset.coms = COM5;
#endif	
	
COMECR = (unsigned long )mstset.coms;
	strcpy(ecr_com, ( (COMECR == COM0)? "COM0" : "COM5" ) );
	
	Com1 = stdperif(ecr_com, &Com2);
	if (Com1)
		fclose(Com1);

	handles=fopen(ecr_com, "rw");
	format(ecr_com,CBR_115200,8,1,NO_PARITY,NO_PARITY,0);
	mask_event (handles , COM_REC_NOT_EMPTY );

	send_receive(handles, ON, ON);
	reset_buf(handles,_receive_id);
	reset_buf(handles,_send_id);


	
	fwrite(ucBuffout,1,len,handles);
	fread(ucBuffout,1,512,handles); //clear all data 
	fclose(handles);
	return;
}
int IngetEnchiper(char *pin, int lenpin, unsigned char *EPin)
{
 	uint8 PANLength,/* track2[41],*/ PANs[16];
       unsigned char TMK[16],TMKLoad[16];
	unsigned char TWK[16],TWKLoad[16];
	//int i=0;
	   
//	PANLength = (uint8)crdGetPANLength(stCardData.puctrack2);
//	crdUnpackTrack2(track2, stCardData.puctrack2);
	//crdUnpackTrack2(track2, stCardData.puctrack2);

	memset(PANs, 0x00, sizeof PANs);
	PANLength=stCardData.unPanlen*2;
	memcpy(PANs, stCardData.pucPan, stCardData.unPanlen*2);
	PANs[PANLength] = 0;	

	memcpy(TMK,profile()->ucTMK1,16);
	memcpy(TWK,profile()->ucTWK1,16);

#ifdef  NO_PINPAD
	memcpy(TMK,"11111111",8);
	memcpy(TWK,"11111111",8);

	SVC_HEX_2_DSP(TWK,TWKLoad,8);
	SVC_HEX_2_DSP(TMK,TMKLoad,8);
	
   #else
	 memcpy(TWKLoad,TWK,16);
	memcpy(TMKLoad,TMK,16);
#endif



	  inGet3DESPin(PANs,pin,lenpin,EPin,TMKLoad,16,TWKLoad,16);
	  return 1;
}


void BCDToString(char *out, uint8 *in, uint8 num)
{
	for (; num-- > 0; in++)
	{ 
		*out++ = *in >> 4 | '0';
		if(*(out-1) == '?')
		{
			*(out-1) = NUL;
			return;
		}
		*out++ = (*in & 0x0F) | '0';
		if(*(out-1) == '?')
		{
			*(out-1) = NUL;
			return;
		}
	}
	*out = NUL;
}

int SetPan( peripread *stswipe)
{
	uint8 	PackedTrack2[19];
	uint8 ucPAN[19];
	  stCardData.unPanlen=MAX_PAN_BNI;
    memcpy(stCardData.puctrack2,stswipe->track2,stswipe->lengthtrack2);
    stCardData.ucTrack2Len=stswipe->lengthtrack2;
  			
			
  crdPackTrack2(PackedTrack2, (uint8*)stswipe->track2+1, strlen(stswipe->track2)-3);
  memcpy(stCardData.pucPan,PackedTrack2,stCardData.unPanlen);
  BCDToString(ucPAN,PackedTrack2,(uint8)crdGetPANLength(PackedTrack2));
  memcpy( stCardData.pucPan,ucPAN,MAX_PAN_BNI*2);
	return 1;
}
int GetPindata(uint8  cmd)
{
int retval;
uint8 password[8], ezPin[8],test[16];
uint8 buff[4];
uint8 tid[8];
int inlenPin=0;
int timeout =0;
memset(tid,0x00,sizeof tid);
 
memset(ezPin,0x00,sizeof ezPin);

  memset(password,0x00,sizeof password);
  if (profile()==NULL)
  	{ retval=ERR_PIN_CANCEL;
  	}
  else {
  	  timeout=25;//atoi(profile()->timepin);// bni want To hardcode 25 second 
  //	memset(tid,'1',8);
//else
  memcpy(tid,profile()->ucTID,8);

     //  if (profile()==NULL)
     if (stCardData.unPanlen>0)
	   	{
	      	    retval=PasswordEntryTime(stCardData.pucPan, stCardData.unPanlen*2,password, 4, 10, 4, 6, TRUE, timeout);
		    if (retval==-1)
			 retval=ERR_PIN_TIMEOUT;
		     else if (retval==0)
			 retval=ERR_PIN_CANCEL;
		     else if (retval >0)
		     	{  inlenPin=retval;
			retval =ERR_PIN_SUCCESS;
		     	}
	  	}
	 else
	 		 retval=ERR_PIN_CANCEL;
  	}
	//  else if (profile()->ucSkmt)
	//	   retval = PinEntry (stCardData.puctrack2,password); 	
	 // else
	  
		
	     if (retval==ERR_PIN_NOCONFIRM)//o
	     	{
	     		memset(buff,0x00,sizeof buff);
				if (cmd==0x77)
					buff[0]=0x78;
				else if  (cmd==0x40)
					buff[0]=0x41; // Fix on Field
				    //  buff[0]=0x08;
				
			 	buff[1]=0x0F;// cancel
			  	memcpy(combuf.data,buff,2);
				 combuf.len=2;
				 
			 	dsppin(0);
	     	}
		else if (retval==ERR_PIN_CANCEL)//o
		{

				memset(buff,0x00,sizeof buff);
				if (cmd==0x77)
					buff[0]=0x78;
				else if  (cmd==0x40)
					buff[0]=0x41;
				
			 	buff[1]=0x0C;// cancel
			  	memcpy(combuf.data,buff,2);
				 combuf.len=2;
				 	
			 	dsppin(0);
		}
		else if (retval==ERR_PIN_TIMEOUT )//-1)
		{
			memset(buff,0x00,sizeof buff);
			if (cmd==0x77)
				buff[0]=0x78;
			else if  (cmd==0x40)
				buff[0]=0x41; // Fix on Field
				//      buff[0]=0x08;
			  buff[1]=0x11;// timeout
		        memcpy(combuf.data,buff,2);
			combuf.len=2;
			
		  	dsppin(1);
		}
		else if (retval==ERR_PIN_SUCCESS)
		{
			memset(buff,0x00,sizeof buff);
			if (cmd==0x77)
				buff[0]=0x78;
			else if (cmd==(0x40))
				buff[0]=0x41; // Fix on Field
				 //     buff[0]=0x08;

			buff[1]=0x3B;//  sukses
                     IngetEnchiper(password,inlenPin,ezPin);
			SVC_HEX_2_DSP	(ezPin,	 test,8);
			memcpy(&buff[2],test,SIZE_PIN_BLOCK);
			memcpy(&buff[2+SIZE_PIN_BLOCK],tid,8);
			memcpy(combuf.data,buff,SIZE_PIN_BLOCK+2+8);
			 
			  combuf.len=SIZE_PIN_BLOCK+2+8;
			  
		}
			
		 _trace("PIN %s %d",buff,retval);

		 	return 0;
	}

int intPushcahar(unsigned char *buff, int len )

{

int i;
	for (i=0;i < len; i++)
		{
					if (buff[i]=='D')
						buff[i]='=';
				}

return 1;
	}

int getSwipeData(uint8  cmd)
{
  peripread stswipe;
  uint8 peripReadRetval=0;
//  int r;
uint8 buff[128];
int lenbuff;
//uint8 pan[16];
  memset(&stswipe,0x00,sizeof( peripread));
memset(buff,0x00,sizeof buff);
  _trace("Swipedata");

 StateHeaders(0);
  pp_display_clear(0);
   pp_settittle("PINPAD");
  vdDisplay3Line("SWIPE", "PLEASE","SWIPE ","CARD");
 peripReadRetval=xx_peripheral_read(&stswipe);
 //peripReadRetval=ucSwiper(&stswipe);
  _trace("Swipedata ret =%d",peripReadRetval);

	switch(peripReadRetval)
	{		
		case prTrackError:
			pp_beep(3);
	              if (cmd==0x07)
			     buff[0]=0x08;
		//	else if  (cmd==0x40)
			//     buff[0]=0x41;
			//buff[0]=0x1B;
			//buff[0]=0x1B;
			buff[1]=0x0D;
			  
			lenbuff=2;
			memcpy(combuf.data,buff,2);
			combuf.len=2;
		       dsppin(2);
			
			return KBD_NO_ENTRY;
			break;

		case prTimeOut:
	
			buff[0]=0x08;
			buff[1]=0x10;
			  
			lenbuff=2;
			memcpy(combuf.data,buff,2);
			combuf.len=2;
			
			 dsppin(1);

			return KBD_TIMEOUT;
			break;
		case prKeyPressed:

			if (stswipe.pValue == VK_CANCEL)
			     {
				buff[0]=0x08;
				buff[1]=0x0C;
				lenbuff=2;
				memcpy(combuf.data,buff,2);
				combuf.len=2;
					
				dsppin(0);

			}
				return 1;


					
				break;
		case prTrackRead: 
			if (stswipe.lengthtrack2==0)
				{
					buff[0]=0x08;
				 	buff[1]=0x10;
				  	lenbuff=2;
					memcpy(combuf.data,buff,2);
					combuf.len=2;
						
				 	dsppin(1);
				 	return KBD_TIMEOUT;
				}
			
			buff[0]=	0x08;
		//	buff[0]=	0x41;
			buff[1]=	0x3B;
			 
			memcpy(&buff[2],&stswipe.track2[1],stswipe.lengthtrack2-1-2);
//			memcpy(&buff[2],&stswipe.track2[0],stswipe.lengthtrack2);
//			lenbuff=stswipe.lengthtrack2+1;
			intPushcahar(buff, stswipe.lengthtrack2-1-2);
			lenbuff=stswipe.lengthtrack2-3 +2 ;
			memcpy(combuf.data,buff,lenbuff);
			combuf.len=lenbuff;


			SetPan(&stswipe);
	//		lenbuff=stswipe.lengthtrack2-1;
//			memcpy(combuf.data,buff,lenbuff);
//			combuf.len=lenbuff;
			
		 	return 0;
			break;
		}

	return 1;
}
unsigned char ucAgentRequest(unsigned  cmd)
{
//int ret;

 pp_open_hmi();
	switch (cmd)
	{
	 case 0x07:
	 	 memset((byte *)&stCardData,0x00,sizeof (stCardData));
		 getSwipeData(cmd);
		 SendResponseToEcr(combuf.data,combuf.len);
              break;
	 
	 case 0x40:	
	 case 0x77:	
		   GetPindata(cmd);
		  SendResponseToEcr(combuf.data,combuf.len);
	 	 memset((byte *)&stCardData,0x00,sizeof (stCardData));

	 	break;
	}
     pp_close_hmi();
    return 1;
}


	
uint8 ucWritetohostM(uint8 * buff, int len  )
	
{
 
	//FMFILE* 			fid;
	//int16 			status;
int 		iRet;
	S_FS_FILE *fh; 
	//disk_create(HOSTNAME,  512 * 1024, 0);

	//	fid = FM_fopen(APP_PAR_FILE_NAME, "a");
			fh= FS_open(APP_PAR_FILE_NAMEM, "a");

		if (fh)
		{
			iRet=FS_write ( buff, 1, len, fh);// != len/2)
//			if((status = FM_fwrite(buff, 1,len,fid)) != (int16)len)
                       if   (iRet!=len)
			{
				//FM_fclose(fid);
				FS_close(fh);
				return 4;
			}

			//FM_fclose(fid);
				FS_close(fh);
		}

	return 0;	
	}

void PushMessage()
{
                       memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_EX,2);
				combuf.len=2;
					ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
					
				StateHeaders(0);
				
				 pp_display_clear(0);
				 pp_settittle("PINPAD");
                        //Display3Line("PROSESS TMS","TERMINAL","SERIAL","FAILED");
				pp_display_text(1,0, "PROSESS ", PT_ALIGN_CENTER);
				pp_display_text(2,0, "UPDATE", PT_ALIGN_CENTER);
				pp_display_text(3,0, "APP", PT_ALIGN_CENTER);
				 buzzer (20);
				ttestall(0, 50);
				ExecutM();
			       pp_get_key(3);
}

unsigned char ucCatchTheMessage(unsigned char *buff,int len )

{
 // stIsoGen   stMsgIso;
// unsigned int ret=0;

 //unsigned char  buffer[999];
 //unsigned int leniso;
 //uint16 t;
  //int j=0;
  unsigned char ucbuffmsg[10];
 int type=-9;
byte ret=0;
int lenbuff;
 if (len==1)
 	{
 	if (!profile())
 		{
	 		
			  memcpy(combuf.data,"\x08\x0D",2);// thi sis Swipe ERROR 
			  combuf.len=2;
			  SendResponseToEcr(combuf.data,combuf.len);
			    StateHeaders(0);
			  pp_display_clear(0);
			  pp_settittle("PINPAD");
			  vdDisplay3Line("ERROR","TERMINAL","NOT","INITIALIZATION");
			   buzzer (7);
			  pp_get_key(5);
			 return 0x00;
 		}
	
 	  ucAgentRequest(buff[0]);
 	} 	
  else if ((len>=2))//&&(buff[0]!=0x00))
  	{ 
  	
	 StateHeaders(0);
	  pp_display_clear(0);
  	  vdDisplay3Line("PROSESS TMS","TERMINAL","INIT","WAIT...");
	 memcpy(ucbuffmsg,&buff[len-8],8);
    
	 if  ( memcmp(ucbuffmsg,TMS_BIT,8)==0)
	 {   _trace4("TMS SELECT");
	   type=0;
	   ret=   ucSelectDataTms(buff,&len,type);
	  }
 else if (( memcmp(ucbuffmsg,APP_BIT,8)==0))
// 	       &&( ( buff[len-1]!=0x44 &&
// buff[len-2]!=0x4E &&
// buff[len-3]!=0x45 )))
 	{ _trace4("APP MASIH ");
       type=1;
	   lenbuff=len-8;
 	ret=ucWritetohostM(buff,lenbuff);
	 //  if ( (len <(3*1024)))
	    //     PushMessage();
 	}
 
 else if ( memcmp(ucbuffmsg,APP_END,8)==0)
//else if ((len <(3*1024)))
 
// else if ( memcmp(ucbuffmsg,APP_END,8)==0)
 
 	{   _trace4("APP END");
       type=2;
	   ret=ucWritetohostM(buff,len-8);
	   if (ret==0)
	   	{
	   	  StateHeaders(0);
				
				 pp_display_clear(0);
				 pp_settittle("PINPAD");
                        //Display3Line("PROSESS TMS","TERMINAL","SERIAL","FAILED");
				pp_display_text(1,0, "PROSESS ", PT_ALIGN_CENTER);
				pp_display_text(2,0, "UPDATE", PT_ALIGN_CENTER);
				pp_display_text(3,0, "APP", PT_ALIGN_CENTER);
	   	ret=21;
                PushMessage();
	   	}
 	
 	}
                 switch (ret)
		// switch (ucSelectDataTms(buff,&len,type))
		 	{

			case 9:
				_trace4("Select 9-> Ko ");
				memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_KO,6);
				  combuf.len=6;
				//	  	 buzzer (5);
				ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
				 StateHeaders(0);
				 pp_display_clear(0);
				  pp_settittle("PINPAD");
				 vdDisplay3Line("PROSESS TMS","TERMINAL","NOT","AUTHORIZE");
				  buzzer (5);
				 pp_get_key(3);
			
				return 0x00;
			  break;
		 	case 5:
				_trace4("Select 5-> Serial  ");
				memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_KO,6);
				 combuf.len=6;
					// buzzer (5);
					ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
				 StateHeaders(0);
				 pp_display_clear(0);
                             pp_settittle("PINPAD");
				 vdDisplay3Line("PROSESS TMS","SERIAL","NOT","MATCH !!");
				  buzzer (5);
					 pp_get_key(3);
					
				return 0x00;
			  break;
		 	case 4:
				_trace4("Select 4-> KO ");
				memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_KO,6);
					combuf.len=6;  
					//	 buzzer (5);
					ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
				
				 StateHeaders(0);
				 pp_display_clear(0);
				  pp_settittle("PINPAD");
                        //Display3Line("PROSESS TMS","TERMINAL","SERIAL","FAILED");
				pp_display_text(1,0, "PROSESS TMS ", PT_ALIGN_CENTER);
				pp_display_text(2,0, "TERMINAL", PT_ALIGN_CENTER);
				pp_display_text(3,0, "INIT FAILED", PT_ALIGN_CENTER);
				 buzzer (5);
					 pp_get_key(3);
				
				return 0x00;

							
				   break;
			case 0:
				_trace4("Select 0-> OK ");
			//	case 17:
				  ret=1;
				   memset(&combuf.data,0x00,BUFFER_MAX);
			 	    memcpy(combuf.data,TMS_OK,6);
					combuf.len=6;
						//	 buzzer (5);
						ttestall(0, 5);
			 	    SendResponseToEcr(combuf.data,combuf.len);


			
				   return 0x00;
				break;
			case 21:
				memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_EX,2);
				combuf.len=2;
					ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
					
				StateHeaders(0);
				
				 pp_display_clear(0);
				 pp_settittle("PINPAD");
                        //Display3Line("PROSESS TMS","TERMINAL","SERIAL","FAILED");
				pp_display_text(1,0, "PROSESS ", PT_ALIGN_CENTER);
				pp_display_text(2,0, "UPDATE", PT_ALIGN_CENTER);
				pp_display_text(3,0, "APP", PT_ALIGN_CENTER);
				 buzzer (20);
				ttestall(0, 50);
				ExecutM();
			       pp_get_key(3);
				break;
			  	default :
									_trace4("Select Default ");
				memset(&combuf.data,0x00,BUFFER_MAX);
				memcpy(combuf.data,TMS_KO,6);
					  combuf.len=6;
					// buzzer (5);
						ttestall(0, 5);
				SendResponseToEcr(combuf.data,combuf.len);
			 	StateHeaders(0);
				 //vdDisplay3Line("PROSESS TMS","TERMINAL","INIT","FAILED");
				 pp_display_clear(0);
				 pp_settittle("PINPAD");
                        //Display3Line("PROSESS TMS","TERMINAL","SERIAL","FAILED");
				pp_display_text(1,0, "PROSESS TMS ", PT_ALIGN_CENTER);
				pp_display_text(2,0, "TERMINAL", PT_ALIGN_CENTER);
				pp_display_text(3,0, "INIT FAILED", PT_ALIGN_CENTER);
					 pp_get_key(3);
				// buzzer (10);
				return 0x00;
				break;
				
		 	}
	
  	}


	return 1;
}
#ifdef APP_ECR

void SendData2ECR(void)
{
	ECR_CallService(0, combuf.data, &combuf.len,COMECR_STR);
	
	if (combuf.len==0||combuf.len==2)
		return;
	
	if (param_comin.action!=DO_CLOSE)
		fclose(handle);
	
	 handle = fopen(COMECR_STR,"rw");
        /* initialize peripheral */
       format(COMECR_STR,CBR_115200,8,1,NO_PARITY,NO_PARITY,0);
	mask_event (handle , COM_REC_NOT_EMPTY ) ;
	send_receive(handle, ON, ON) ;
	reset_buf(handle,_receive_id);	
	reset_buf(handle,_send_id);		
	if (combuf.len)
		fwrite(combuf.data, 1, combuf.len, handle);	
	
	if (param_comin.action==DO_CLOSE)
		fclose(handle);

}


uint32 bcdtobin(uint8 const* src, uint8 num_digits)
{
	char tmpbuf[128];
	//uint32 tmp;
//	if(aanTest==4)
//		hex_dump("src", (uint8*)src, 4);
	Hexasc((byte*)tmpbuf,(byte*)src,num_digits);
	tmpbuf[num_digits]=0x00;
	
	//Ascbin(&tmp,(byte*)tmpbuf,strlen(tmpbuf));
	return atol(tmpbuf);
}

int ECR_CallService(int no, byte *buffer, int *len, char *com_ecr)
{

	ST_InterApp st_it;	
	unsigned char ber[8];
	memset(ber,0x00,8);

	st_it.serviceid= EVMSG_ECR_CALL;
		st_it.no=no;
		
		memcpy(st_it.par_in.in_ecr.data, buffer, *len);
		memcpy(st_it.par_in.in_ecr.com_ecr, com_ecr, sizeof com_ecr);
		st_it.par_in.in_ecr.len=*len;
		//CallClientEvent(appid_act,&st_it);
		//_trace_DSP2("BUFF", combuf.data,combuf.len);
               _trace4("DATA BUFF OK %ld",combuf.len);
		// if (combuf.data[0]!=0x00)
		   ucCatchTheMessage(combuf.data,combuf.len);
		//memset(buffer,0x00, *len);
		_trace4("123");
		memcpy(buffer, st_it.par_out.out_ecr.data, st_it.par_out.out_ecr.len);
		*len=st_it.par_out.out_ecr.len;
	

/*
	   appid_act=GetAppID(EVMSG_ECR_CALL);
	   if (appid_act)
	  {
		st_it.serviceid= EVMSG_ECR_CALL;
		st_it.no=no;
		memcpy(st_it.par_in.in_ecr.data, buffer, *len);
		memcpy(st_it.par_in.in_ecr.com_ecr, com_ecr, sizeof com_ecr);
		st_it.par_in.in_ecr.len=*len;
		CallClientEvent(appid_act,&st_it);
		//memset(buffer,0x00, *len);
		memcpy(buffer, st_it.par_out.out_ecr.data, st_it.par_out.out_ecr.len);
		*len=st_it.par_out.out_ecr.len;
	}
	   */
	   return FCT_OK;
}


int CheckGetMessage(byte* msg, int *lenmsg)//byte *data, int len
{
	uint16 iLoop, len;
	byte tmpBuf[300];
	
	tmpBuf[0]=0x00;

	if (msg[0]!=STX)
		return !RET_OK;

	//count crc n then check it
	for(iLoop=0; iLoop < ((*lenmsg)-1); iLoop++)
		tmpBuf[0] ^= *(msg + iLoop);
		
	if(tmpBuf[0] != *(msg + ((*lenmsg)-1)))//crc not match
		return !RET_OK;

	//match, get the len 
	len = 0;
	len = (uint16)bcdtobin(msg+1, 4);
	
	if (((*lenmsg)-5)!=len)
		return !RET_OK;

	return RET_OK;
}

void ECR_transaction(FILE *HCom)
{
	combuf.len=fread(combuf.data,1,BUFFER_MAX,HCom);
	
	if (combuf.len==1)
	{

		if ((combuf.data[0]==0x15)&&combuf.NeedSendAgain)
		{
			combuf.len=5;//credit application will built same response again
			combuf.NeedSendAgain=0;
		}
		else
		{
			combuf.NeedSendAgain=0;
		}
	}
/*
	else if(CheckGetMessage(combuf.data, &combuf.len)!=RET_OK)
	{
		combuf.NeedSendAgain=0;
		fwrite((byte*)"\x15",1,1,HCom);
	}
	else	
	{
		combuf.NeedSendAgain=1; //flag : if next response get "NACK" EDC will send message again
		fwrite((byte*)"\x06",1,1,HCom);
	}
	*/

}


/* protocol task */
void Task_Protocole(void)
{

  unsigned int   cr;          /* Result of ttestall                            */
  unsigned int   mask;        /* Mask of event to wait depending of task state */
 //FILE *handle=NULL;
 
  /* Task is waiting for DO_OPEN */
  task_state = TASK_OPEN;
  //handle=NULL;
  /* Only synchronisation to wait */
  mask       = DIALOG;
  /* Task is now operationnal */
  SignalEvent(m2os_task,EVT_DIALOG);

  while (1)
  {
    cr = ttestall(mask,0);

	/* Initialize returned structure */
	/* Appli number */
    param_comout.no_appli = appli_number;
	/* Handle of peripheral , not used */
    param_comout.handle   = NULL;
	/* function return */
    param_comout.cr       = CR_DIALOGUE_OK;

	switch (task_state)
	{
      case TASK_OPEN :
	  	//_trace("open thread");
		_trace( "ECR: before TASK_OPEN" );
		/* Only DO_OPEN is accepted in this state */
		if (param_comin.action==DO_OPEN)
		{
			// _trace( "ECR: DO_OPEN" );
         		 /* Open all protocol peripheral (for example COM0) */
		       handle = fopen(COMECR_STR,"rw");
		        /* initialize peripheral */
		        /* 9600 bauds,8 bits, 1 stop bit,no parity */
		       //format("COM0",CBR_9600,1,NO_PARITY,EVEN,0);
		       format(COMECR_STR,CBR_115200,8,1,NO_PARITY,NO_PARITY,0);
			mask_event (handle , COM_REC_NOT_EMPTY ) ;
			send_receive(handle, ON, ON) ;
			reset_buf(handle,_receive_id);	
			reset_buf(handle,_send_id);	
		  	/* We are now waiting for serial link and synchronization */
		  	mask = COMECR | DIALOG;
			
		  	/* New state */
		  	task_state = TASK_RECEPT;
		}
        	/* Traitment is over */
        	SignalEvent(m2os_task,EVT_DIALOG);
		//_trace( "ECR: after TASK_OPEN" );
		break;

      case TASK_RECEPT :
		_trace( "ECR: before TASK_RECEPT" );
		switch (cr)
		{
		  	case DIALOG :
				//_trace( "ECR: dialog" );
		    		/* Only DO_CLOSE is accepted in this state */
		    		if (param_comin.action==DO_CLOSE)
				{
					//_trace( "ECR: DO_CLOSE" );
			      		/* New state */
			      		task_state = TASK_OPEN;
	              		/* Close all protocol peripheral (for example COM0) */
	              		fclose(handle);
					handle=NULL;
	              		/* Only synchronisation to wait */
	             			 mask       = DIALOG;
		    		  }
					
	            		/* Traitment is over */
	            		SignalEvent(m2os_task,EVT_DIALOG);			
				break;
			case COM1:
			case COM5:	 // imam 
		  	case COM0 :
				//_trace( "ECR: COM0" );
            			/* Task want to manage something from serial link */
  	        		/* New state */
		    		task_state = TASK_READING;
            			/* Only synchronisation to wait */
            			mask       = DIALOG;
            			/* Traitment is over */
            			SignalEvent(m2os_task,EVT_DIALOG);
				break;
		}
//		_trace( "ECR: after TASK_RECEPT" );
		break;
	  case TASK_READING :
		_trace( "ECR: before TASK_READING" );
		/* Only DO_RECEPT is accepted in this state */
		if (param_comin.action==DO_RECEPT)
		{
			//_trace( "ECR: DO_RECEPT" );
			  /*-------------------------------------------*/
			  /* Put protocol management here              */
			  /*          for example                      */
			  /* Read from COM0 and print data received    */
			  /*-------------------------------------------*/
		      /* nothing */
			 ttestall(0,5);			  
			 ECR_transaction(handle);
			  /* New state */
		      	task_state = TASK_RECEPT;
			  /* We are now waiting for serial link and synchronization */
			  mask = COMECR | DIALOG;
		}
        	/* Traitment is over */
       	SignalEvent(m2os_task,EVT_DIALOG);

		//_trace( "ECR: after TASK_READING" );
		break;
	}
  }

}


void initECR(NO_SEGMENT no)
{
	memset((byte*)&combuf, 0x00, sizeof(combuf));

	memset(&mstset, 0x00, sizeof(mstset));
	#ifdef NO_PINPAD
	if(GetSetting(&mstset)!=RET_OK)//unable to read the setting, set default to COM0 for ECR comm
		mstset.coms = COM0;
	#else
	if(GetSetting(&mstset)!=RET_OK)//unable to read the setting, set default to COM0 for ECR comm
		mstset.coms = COM5;
	#endif

	#ifdef NO_PINPAD
			mstset.coms = COM0;
	#else
		mstset.coms = COM5;
	#endif
	COMECR = (unsigned long )mstset.coms;
	strcpy(COMECR_STR, ( (COMECR == COM0)? "COM0" : "COM5" ) );




	/* Remember my application number */
	appli_number = no;

	// Remember task number of M2OS
	m2os_task = CurrentTask();
	
	// Force Cash Connection
	PSQ_Update_Cash_Connection(cash_connection_on);
	
	//protocole_stack=umalloc(sizeof(unsigned long)*PROTOCOLE_STACK_SIZE);
	// Start Protocol Task
	pttask = (t_topstack *) fork((PFONCFORK)Task_Protocole, (unsigned char *)&protocole_stack[PROTOCOLE_STACK_SIZE], SYSTEM_STACK_SIZE);

	// Waiting for task to be started
	ttestall(DIALOG,0);
}

int com_event(NO_SEGMENT no, S_COMIN * param_in,     S_COMOUT  *param_out)
{
_trace( "COM EVENT" );

	if(com_is_busy == TRUE)
		return STOP;

	com_is_busy = TRUE;
	memcpy((char *)&param_comin, (char *)param_in, sizeof(S_COMIN));
	
	switch(param_in->action)
	{
		case DO_OPEN :
		case DO_RECEPT :
		case DO_CLOSE :	
			/* because of MMU, GiveNoTack is use to read an element of pttask */
			/* Signal to protocle task that something is to do               */
			/* The action is available into param_comin variable              */
			//_trace( "ECR: ComEvent: action=%x",&param_in->action);

			SignalEvent(GiveNoTask(pttask),EVT_DIALOG);
			/* Wait the end of traitment */
			//_trace( "ECR:Doing thread now!" );
			ttestall(DIALOG,0);
			//_trace( "ECR:Done thread!" );
			/* Copy result of traitment */
			memcpy((char *)param_out,(char *)&param_comout,sizeof(S_COMOUT));
		break;
	}
	
	if ((param_in->action==DO_CLOSE) && (combuf.len))
		com_is_busy = TRUE;
	else
		com_is_busy = FALSE;

	return(FCT_OK);
}

#endif

int fall_back(NO_SEGMENT no, S_TRANSIN *param_in,  S_TRANSOUT * param_out)// void* param_out)
{
#if 0
	int ret_code;
	ST_InterApp st_it;

	st_it.serviceid=EVMSG_FALLBACK;
	st_it.no=no;
	_trace("fall_back");
	memcpy(&(st_it.par_in.in_fall_back), param_in, sizeof(S_TRANSIN));	
	ret_code= CallClientEvent(appid_act,&st_it); 
	memcpy(param_out, &(st_it.par_out.out_select_aid_extended), sizeof(S_AID_OUT));
#endif
	//return ret_code;
	return FCT_OK;//CallClientEvent(appid_act,EVMSG_FALLBACK,param_in,param_out,no);
}

void test(void)
{
	FILE *fl;
	fl=fopen("DISPLAY","w");	

	pp_display_text(2, 0, "AMERICAN EXPRESS", PT_ALIGN_CENTER | PT_CLEAR);
	pp_display_text(3, 0, "INSERT/SWIPE", PT_ALIGN_CENTER | PT_CLEAR);
	PaintGraphics();
	fclose(fl);

}

void AnimSwipe(void)
{
	FILE *fl;
	int fnt;

	char tmp[50];
	uint8 xs, ys;

	//uint8 l;
	DATE tmpDate;
	
	fl=fopen("DISPLAY","w");	

	_clrscr();
	PaintGraphics();
	
	if(pp_get_hardware_type() == TYPE_TERMINAL_SMART)// nazar, add on EFTSMART
		{
			read_date(&tmpDate);
		}

	
	fnt=GetDefaultFont();
	_clrscr();
	SetType(_PROPORTIONNEL_);	

	if(pp_get_hardware_type() == TYPE_TERMINAL_SMART)	// nazar, add on EFTSMART
	{
	#ifdef NO_PINPAD
		//date
		memset(tmp,' ',sizeof(tmp));
		memcpy(tmp, tmpDate.day, 2);
		tmp[2]=tmp[5]='/';
		memcpy(&tmp[3], tmpDate.month, 2);
		memcpy(&tmp[6], "20", 2);
		memcpy(&tmp[8], tmpDate.year, 2);
		//time
		memcpy(&tmp[11], tmpDate.hour, 2);
		tmp[13]=':';
		memcpy(&tmp[14], tmpDate.minute, 2);
		tmp[16]='\0';
		SetArea(0, 0, 128, 23,_OFF_);
		DrawString(tmp, 0, 0, _OFF_);
		#else
		//date
		memset(tmp,' ',sizeof(tmp));
		memcpy(tmp, tmpDate.day, 2);
		tmp[2]=tmp[5]='/';
		memcpy(&tmp[3], tmpDate.month, 2);
		memcpy(&tmp[6], "20", 2);
		memcpy(&tmp[8], tmpDate.year, 2);
		//time
		memcpy(&tmp[15+10], tmpDate.hour, 2);
		tmp[17+10]=':';
		memcpy(&tmp[18+10], tmpDate.minute, 2);
		tmp[20+10]='\0';
		SetArea(0, 0, 128, 23+8,_OFF_);
		DrawString(tmp, 0, 0, _OFF_);
		#endif
	}

	
	//PaintGraphics();
	//SetType(_PROPORTIONNEL_);	
	//SetType(_NORMALE_);	
	if(pp_get_hardware_type() == TYPE_TERMINAL_SMART)	// nazar, add on EFTSMART	
		{
			SetBitmap(0, 20, (unsigned char*)idle_logo,_OFF_);
		}
	else
		{	// assume it's 930G
			SetBitmap(0, 20, (unsigned char*)idle_logo,_OFF_);
		}

	SetArea(0, 52, 128, 60,_OFF_);
	//SetArea(0, 52, 128, 60,_ON_);
	memset(tmp,' ',sizeof(tmp));
	tmp[50]='\0';
	xs = 0;
	ys = 54;// 52
#if 0	
	switch(animFlag)
		{
		case 0:
//			strcpy(tmp, "SWIPE CARD              ");
//			xs = 35;
//			animFlag++;
//			break;
		case 1:
			strcpy(tmp, "F1 : MORE MENU          ");
			xs = 26;// 30;
			animFlag++;
			break;
		case 2:
			strcpy(tmp, "F4: SETTLE              ");
			xs = 35;
			animFlag++;
			break;
		case 3:
			strcpy(tmp, "F2: REPRINT LAST        ");
			xs = 21;// 25;
			animFlag++;
			break;
		case 4:
			strcpy(tmp, "F3: REPRINT  ANY        ");
			xs = 21;// 25;
			animFlag=0;
			break;
		}
#else
	//		strcpy(tmp, "INSERT/SWIPE");
			strcpy(tmp, "           PINPAD");

			xs = 21;// 25;
#endif
//DrawString(tmp, xs,ys,_OFF_);  
	DrawString(tmp, xs, ys, _OFF_);
//DrawExtendedString(xs, ys, tmp, _OFF_, _POLICE5x7_, _NORMALE_);
		
	PaintGraphics();			

	//SetFont(fnt);
	SetDefaultFont(fnt);
	fclose(fl);
	
}


int idle_message (NO_SEGMENT no,void *p1,void *p2)
{
/*
	FILE *hDisplay;
	int nFont;
	int i,y,k;
	char tmp[100];
	
	// Open the display driver.
	hDisplay = fopen("DISPLAY","w");
	
	nFont = GetDefaultFont();

	//StateHeader(1);//DisplayHeaderStatus);
	//CreateGraphics(_MEDIUM_);	
	_clrscr();
	PaintGraphics();//disable
//	SetBitmap(0, 23, (unsigned char*)kartuku,_OFF_);
//	SetArea(0, 52, 128, 65,_OFF_);
	
	
	SetType(_PROPORTIONNEL_);//disable
	CreateGraphics(_MEDIUM_);//disable
	
	for (i=0;i<totapreg.totapp;i++)
	{
		if (i<3)
		{
			sprintf(tmp,"%d-%s",i+1, totapreg.stap[i].appname);
			DrawString(tmp,1,23+(i*12),_OFF_);  	  			
		}
		else
		{
			y=i-3;		
			sprintf(tmp,"%s-%d", totapreg.stap[i].appname,i+1);
			k=127-StringWidth(tmp);
			DrawString(tmp,k,23+(y*12),_OFF_);  
		}
	}
	
//	DrawExtendedString(15, 54, "SWIPE/INSERT CARD", _OFF_, _POLICE5x7_, _NORMALE_);
	PaintGraphics();		

	SetDefaultFont( nFont );
	fclose( hDisplay );
*/
	StateHeaders(1);
	_clrscr();
	PaintGraphics();

	AnimSwipe();
	return (FCT_OK);
}

byte checkapp(unsigned short apptype)
{
	int i;
	for (i=0;i<totapreg.totapp;i++)
	{
		if (totapreg.stap[i].apptype==apptype)
			return TRUE;
	}
	
	return FALSE;	
}


int GetApplist(int size, ST_applist *Data)
{
	int t;
	byte k;
	
	k=checkapp(Data->apptype);	
	Data->retval=FALSE;	
	if (!k)
	{
		t=totapreg.totapp;
		memcpy(&totapreg.stap[t], Data, sizeof(ST_applist));		
		totapreg.totapp++;
		Data->retval=TRUE;	
	}
	else
		Data->retval=FALSE;
			
	return FCT_OK;
}


typedef struct
{
    	unsigned short type_code;
	unsigned short service;
	unsigned long m_ulAmount;
	int m_nCurrencyCode;
} T_PERFORM_PAYMENT;

int PerformPayment(unsigned int size, T_PERFORM_PAYMENT* pPaymentData)
{	
	unsigned char priority;
	unsigned int  ret_code;
	//int DisplayHeaderStatus;
	
	if (!appid_act)
		return (FCT_OK);
	
	if (ServiceGet(appid_act,I_EMVCUST_Perform_Transaction,&priority)==0)	
	{
		//DisplayHeaderStatus=StateHeader(0); //disable display header	
		StateHeaders(0);
		USR_ServiceCall(appid_act, I_EMVCUST_Perform_Transaction, sizeof(T_PERFORM_PAYMENT), (void*)pPaymentData,&ret_code);	
		//StateHeader(DisplayHeaderStatus);
		return ret_code;
	}
	
  	return (FCT_OK);	
}

typedef int (*T_SERVICE_FUNCTION)(unsigned int nSize, void*Data);

int give_interface(unsigned short no,void *p1,void *p2)
{

 service_desc_t MesServices[]=
	{
		{no	,IS_NAME						,(SAP)Main						,10},
		{no	,MORE_FUNCTION					,(SAP)Main						,10},
		{no	,IDLE_MESSAGE					,(SAP)Main						,70},
		{no	,KEYBOARD_EVENT				,(SAP)Main						,30},
		{no	,AFTER_RESET					,(SAP)Main						,30},
		{no	,CONSULT						,(SAP)Main						,30},
		{no	,STATE							,(SAP)Main						,30},
		{no	,IS_CHANGE_INIT					,(SAP)Main						,30},
		{no	,IS_EVOL_PG						,(SAP)Main						,30},
		{no	,IS_STATE						,(SAP)Main						,30},
		{no	,IS_TIME_FUNCTION				,(SAP)Main						,30},
		{no	,MCALL							,(SAP)Main						,30},
		{no	,MODIF_PARAM					,(SAP)Main						,30},
		{no	,IS_FOR_YOU_BEFORE				,(SAP)Main						,30},
		{no	,DEBIT_NON_EMV					,(SAP)Main						,30},
		{no	,DEBIT_EMV						,(SAP)Main						,30},		
		{no	,FILE_RECEIVED					,(SAP)Main						,30},
		{no	,GIVE_YOUR_DOMAIN				,(SAP)Main						,30},
		{no	,IS_FOR_YOU_AFTER				,(SAP)Main						,30},
		{no	,IS_DELETE 						,(SAP)Main						,30},
	#ifdef APP_ECR	
		{no, COM_EVENT						,(SAP)Main						,30},
	#endif
		{no	,FALL_BACK 						,(SAP)Main						,30},

		{no	,SELECT_AID_EXTENDED 			,(SAP)Main						,30},
		{no	,TRACK_STREAM 					,(SAP)Main						,30},
		{no	,SELECT_AID 						,(SAP)Main						,30},		
		{no	,SERVICE_APPREG_CALL			,(SAP)GetApplist					,10},
		{no	,SERVICE_HMI_CALL				,(SAP)Service_HMI_call			,10},		
		{no	,I_EMVCUST_Perform_Transaction	,(SAP)PerformPayment			,30},
		
		{no	,I_EMVCUST_Initialise 				,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_Global_Param 		,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_AID_List 			,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_AID_DATA 		,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_AID_Param 		,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_More_Function 			,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Periodic_Call 			,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Process_Step 			,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Display_Message 		,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_Last_Transaction	,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Voice_Referral 			,(SAP)Main_EMVCUST				,30},
		{no	,I_EMVCUST_Get_AID 				,(SAP)Main_EMVCUST				,30},
	#ifndef _FULLEMV_	
		{no	,I_EMVCUST_KeyManagement 		,(SAP) Main_EMVCUST				,30},
	#endif	
		{no	,I_EMVCUST_Authorisation 			,(SAP) Main_EMVCUST				,30},
		{no	,I_EMVCUST_Choose_Language_Menu ,(SAP) Main_EMVCUST				,30},
		{no	,I_EMVCUST_Menu_Select 			,(SAP) Main_EMVCUST				,30},		
		{no	,I_EMVCUST_Choose_Account_Type_Menu, 	(SAP) Main_EMVCUST		,30},
		//{no	,SERVICE_HMI_CALL 				, (SAP) Service_HMI_call			,30}	
#ifdef IMAM_COMMS		
		{no	,SERVICE_COMMS_EXCHANGE, 	(SAP) Service_COMMS		,30},
#endif		
	};
	
	
	int 	i = sizeof(MesServices)/sizeof(service_desc_t);			

	appid_act=0;
	ServiceRegister(i,MesServices);

	return FCT_OK;
}

void entry(void)
{
	object_info_t info;
	
	
	ObjectGetInfo(OBJECT_TYPE_APPLI, ApplicationGetCurrent(),&info);
	
	give_interface(info.application_type, NULL, NULL);

	// Open all the external libraries.

	paramlib_open();	// TELIUM Manager Library 
	extenslib_open();	// Extension Library 
	svlib_open();		// SV Library (for date management).
	libgrlib_open();	// Graphic Library 
	entrylib_open();	//
#ifndef _SIMULPC_
    PPS_Dll_init();
#endif

#ifdef IMAM_COMMS
	 gprslib_open();
	#ifdef _SSL_ENABLE_
		  ssllib_open();
	#endif
#endif
/*
	paramlib_open();	// TELIUM Manager Library 
	entrylib_open();		//
	
#ifndef _SIMULPC_
	  emvsqlib_open();
	  extenslib_open();
	  libgrlib_open();
	  saisielib_open();
	  paramlib_open();
	  svlib_open();
	  dllpsclib_open();
	  pinpadlib_open();
	  languelib_open();
	  protocolelib_open();
	  cb2alib_open();
	  iamlib_open();
	  partagelib_open();
	  Crypto_Dll_Open();
	  gprslib_open();
	  PPS_Dll_Open();

#ifdef _USE_DLL_SECURITY_
	SEClib_Open();
#endif

#ifndef IMAM_COMMS	  
	#ifdef _SSL_ENABLE_
	  ssllib_open();
	#endif
#endif
*/
	
}

//aan
char * dpmThisApplicationName(void)
{
	static	char 	AppliName[30];
	int rc,on;
	object_info_t info;

//	AppliName[0] = NUL;
	memset(AppliName, 0x00, sizeof(AppliName));

	on=ObjectGetNumber(OBJECT_TYPE_APPLI);
	//rc=ObjectGetInfo( OBJECT_TYPE_APPLI,0,&info);
	rc=ObjectGetInfo( OBJECT_TYPE_APPLI,(unsigned int)ApplicationGetCurrent(),&info);

	if (rc)
		return NULL;
	
	memcpy(AppliName,info.name,OBJECT_NAME_LEN);
	//strcat(AppliName,"-");
	//strcat(AppliName,info.file_name);
	AppliName[16] = '\0';;

	return AppliName;
}



